diff --git a/samples/backups-cancel.js b/samples/backups-cancel.js index cae7a0cde..cbe1fae7b 100644 --- a/samples/backups-cancel.js +++ b/samples/backups-cancel.js @@ -15,7 +15,7 @@ 'use strict'; -async function cancelBackup(instanceId, databaseId, backupId, projectId) { +function main(instanceId, databaseId, backupId, projectId) { // [START spanner_cancel_backup_create] // Imports the Google Cloud client library and precise date library @@ -37,47 +37,54 @@ async function cancelBackup(instanceId, databaseId, backupId, projectId) { const databaseAdminClient = spanner.getDatabaseAdminClient(); // Creates a new backup of the database - try { - console.log( - `Creating backup of database ${databaseAdminClient.databasePath( - projectId, - instanceId, - databaseId - )}.` - ); - - // Expire backup one day in the future - const expireTime = Date.now() + 1000 * 60 * 60 * 24; - const [operation] = await databaseAdminClient.createBackup({ - parent: databaseAdminClient.instancePath(projectId, instanceId), - backupId: backupId, - backup: (protos.google.spanner.admin.database.v1.Backup = { - database: databaseAdminClient.databasePath( + async function cancelBackup() { + try { + console.log( + `Creating backup of database ${databaseAdminClient.databasePath( projectId, instanceId, databaseId - ), - expireTime: Spanner.timestamp(expireTime).toStruct(), - name: databaseAdminClient.backupPath(projectId, instanceId, backupId), - }), - }); + )}.` + ); - // Cancel the backup - await operation.cancel(); + // Expire backup one day in the future + const expireTime = Date.now() + 1000 * 60 * 60 * 24; + const [operation] = await databaseAdminClient.createBackup({ + parent: databaseAdminClient.instancePath(projectId, instanceId), + backupId: backupId, + backup: (protos.google.spanner.admin.database.v1.Backup = { + database: databaseAdminClient.databasePath( + projectId, + instanceId, + databaseId + ), + expireTime: Spanner.timestamp(expireTime).toStruct(), + name: databaseAdminClient.backupPath(projectId, instanceId, backupId), + }), + }); - console.log('Backup cancelled.'); - } catch (err) { - console.error('ERROR:', err); - } finally { - // Delete backup in case it got created before the cancel operation - await databaseAdminClient.deleteBackup({ - name: databaseAdminClient.backupPath(projectId, instanceId, backupId), - }); - // Close the spanner client when finished. - // The databaseAdminClient does not require explicit closure. The closure of the Spanner client will automatically close the databaseAdminClient. - spanner.close(); + // Cancel the backup + await operation.cancel(); + + console.log('Backup cancelled.'); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Delete backup in case it got created before the cancel operation + await databaseAdminClient.deleteBackup({ + name: databaseAdminClient.backupPath(projectId, instanceId, backupId), + }); + // Close the spanner client when finished. + // The databaseAdminClient does not require explicit closure. The closure of the Spanner client will automatically close the databaseAdminClient. + spanner.close(); + } } + cancelBackup(); // [END spanner_cancel_backup_create] } -module.exports.cancelBackup = cancelBackup; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups-create-with-encryption-key.js b/samples/backups-create-with-encryption-key.js index 008a2b6ea..9cf67fc5d 100644 --- a/samples/backups-create-with-encryption-key.js +++ b/samples/backups-create-with-encryption-key.js @@ -15,13 +15,7 @@ 'use strict'; -async function createBackupWithEncryptionKey( - instanceId, - databaseId, - backupId, - projectId, - keyName -) { +function main(instanceId, databaseId, backupId, projectId, keyName) { // [START spanner_create_backup_with_encryption_key] // Imports the Google Cloud client library @@ -47,68 +41,75 @@ async function createBackupWithEncryptionKey( const databaseAdminClient = spanner.getDatabaseAdminClient(); // Creates a new backup of the database - try { - console.log( - `Creating backup of database ${databaseAdminClient.databasePath( - projectId, - instanceId, - databaseId - )}.` - ); - - // Expire backup 14 days in the future - const expireTime = Date.now() + 1000 * 60 * 60 * 24 * 14; - - // Create a backup of the state of the database at the current time. - const [operation] = await databaseAdminClient.createBackup({ - parent: databaseAdminClient.instancePath(projectId, instanceId), - backupId: backupId, - backup: (protos.google.spanner.admin.database.v1.Backup = { - database: databaseAdminClient.databasePath( + async function createBackupWithEncryptionKey() { + try { + console.log( + `Creating backup of database ${databaseAdminClient.databasePath( projectId, instanceId, databaseId - ), - expireTime: Spanner.timestamp(expireTime).toStruct(), - name: databaseAdminClient.backupPath(projectId, instanceId, backupId), - }), - encryptionConfig: { - encryptionType: 'CUSTOMER_MANAGED_ENCRYPTION', - kmsKeyName: keyName, - }, - }); + )}.` + ); - console.log( - `Waiting for backup ${databaseAdminClient.backupPath( - projectId, - instanceId, - backupId - )} to complete...` - ); - await operation.promise(); + // Expire backup 14 days in the future + const expireTime = Date.now() + 1000 * 60 * 60 * 24 * 14; + + // Create a backup of the state of the database at the current time. + const [operation] = await databaseAdminClient.createBackup({ + parent: databaseAdminClient.instancePath(projectId, instanceId), + backupId: backupId, + backup: (protos.google.spanner.admin.database.v1.Backup = { + database: databaseAdminClient.databasePath( + projectId, + instanceId, + databaseId + ), + expireTime: Spanner.timestamp(expireTime).toStruct(), + name: databaseAdminClient.backupPath(projectId, instanceId, backupId), + }), + encryptionConfig: { + encryptionType: 'CUSTOMER_MANAGED_ENCRYPTION', + kmsKeyName: keyName, + }, + }); - // Verify backup is ready - const [backupInfo] = await databaseAdminClient.getBackup({ - name: databaseAdminClient.backupPath(projectId, instanceId, backupId), - }); - if (backupInfo.state === 'READY') { console.log( - `Backup ${backupInfo.name} of size ` + - `${backupInfo.sizeBytes} bytes was created at ` + - `${new PreciseDate(backupInfo.createTime).toISOString()} ` + - `using encryption key ${backupInfo.encryptionInfo.kmsKeyVersion}` + `Waiting for backup ${databaseAdminClient.backupPath( + projectId, + instanceId, + backupId + )} to complete...` ); - } else { - console.error('ERROR: Backup is not ready.'); + await operation.promise(); + + // Verify backup is ready + const [backupInfo] = await databaseAdminClient.getBackup({ + name: databaseAdminClient.backupPath(projectId, instanceId, backupId), + }); + if (backupInfo.state === 'READY') { + console.log( + `Backup ${backupInfo.name} of size ` + + `${backupInfo.sizeBytes} bytes was created at ` + + `${new PreciseDate(backupInfo.createTime).toISOString()} ` + + `using encryption key ${backupInfo.encryptionInfo.kmsKeyVersion}` + ); + } else { + console.error('ERROR: Backup is not ready.'); + } + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the spanner client when finished. + // The databaseAdminClient does not require explicit closure. The closure of the Spanner client will automatically close the databaseAdminClient. + spanner.close(); } - } catch (err) { - console.error('ERROR:', err); - } finally { - // Close the spanner client when finished. - // The databaseAdminClient does not require explicit closure. The closure of the Spanner client will automatically close the databaseAdminClient. - spanner.close(); } + createBackupWithEncryptionKey(); // [END spanner_create_backup_with_encryption_key] } -module.exports.createBackupWithEncryptionKey = createBackupWithEncryptionKey; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups-create.js b/samples/backups-create.js index 6af1578cc..797293664 100644 --- a/samples/backups-create.js +++ b/samples/backups-create.js @@ -15,13 +15,7 @@ 'use strict'; -async function createBackup( - instanceId, - databaseId, - backupId, - projectId, - versionTime -) { +function main(instanceId, databaseId, backupId, projectId, versionTime) { // [START spanner_create_backup] // Imports the Google Cloud client library and precise date library @@ -46,66 +40,73 @@ async function createBackup( const databaseAdminClient = spanner.getDatabaseAdminClient(); // Creates a new backup of the database - try { - console.log( - `Creating backup of database ${databaseAdminClient.databasePath( - projectId, - instanceId, - databaseId - )}.` - ); - - // Expire backup 14 days in the future - const expireTime = Date.now() + 1000 * 60 * 60 * 24 * 14; - - // Create a backup of the state of the database at the current time. - const [operation] = await databaseAdminClient.createBackup({ - parent: databaseAdminClient.instancePath(projectId, instanceId), - backupId: backupId, - backup: (protos.google.spanner.admin.database.v1.Backup = { - database: databaseAdminClient.databasePath( + async function createBackup() { + try { + console.log( + `Creating backup of database ${databaseAdminClient.databasePath( projectId, instanceId, databaseId - ), - expireTime: Spanner.timestamp(expireTime).toStruct(), - versionTime: Spanner.timestamp(versionTime).toStruct(), - name: databaseAdminClient.backupPath(projectId, instanceId, backupId), - }), - }); + )}.` + ); - console.log( - `Waiting for backup ${databaseAdminClient.backupPath( - projectId, - instanceId, - backupId - )} to complete...` - ); - await operation.promise(); + // Expire backup 14 days in the future + const expireTime = Date.now() + 1000 * 60 * 60 * 24 * 14; + + // Create a backup of the state of the database at the current time. + const [operation] = await databaseAdminClient.createBackup({ + parent: databaseAdminClient.instancePath(projectId, instanceId), + backupId: backupId, + backup: (protos.google.spanner.admin.database.v1.Backup = { + database: databaseAdminClient.databasePath( + projectId, + instanceId, + databaseId + ), + expireTime: Spanner.timestamp(expireTime).toStruct(), + versionTime: Spanner.timestamp(versionTime).toStruct(), + name: databaseAdminClient.backupPath(projectId, instanceId, backupId), + }), + }); - // Verify backup is ready - const [backupInfo] = await databaseAdminClient.getBackup({ - name: databaseAdminClient.backupPath(projectId, instanceId, backupId), - }); - if (backupInfo.state === 'READY') { console.log( - `Backup ${backupInfo.name} of size ` + - `${backupInfo.sizeBytes} bytes was created at ` + - `${new PreciseDate(backupInfo.createTime).toISOString()} ` + - 'for version of database at ' + - `${new PreciseDate(backupInfo.versionTime).toISOString()}` + `Waiting for backup ${databaseAdminClient.backupPath( + projectId, + instanceId, + backupId + )} to complete...` ); - } else { - console.error('ERROR: Backup is not ready.'); + await operation.promise(); + + // Verify backup is ready + const [backupInfo] = await databaseAdminClient.getBackup({ + name: databaseAdminClient.backupPath(projectId, instanceId, backupId), + }); + if (backupInfo.state === 'READY') { + console.log( + `Backup ${backupInfo.name} of size ` + + `${backupInfo.sizeBytes} bytes was created at ` + + `${new PreciseDate(backupInfo.createTime).toISOString()} ` + + 'for version of database at ' + + `${new PreciseDate(backupInfo.versionTime).toISOString()}` + ); + } else { + console.error('ERROR: Backup is not ready.'); + } + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the spanner client when finished. + // The databaseAdminClient does not require explicit closure. The closure of the Spanner client will automatically close the databaseAdminClient. + spanner.close(); } - } catch (err) { - console.error('ERROR:', err); - } finally { - // Close the spanner client when finished. - // The databaseAdminClient does not require explicit closure. The closure of the Spanner client will automatically close the databaseAdminClient. - spanner.close(); } + createBackup(); // [END spanner_create_backup] } -module.exports.createBackup = createBackup; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups-delete.js b/samples/backups-delete.js index 27189c3c9..959388679 100644 --- a/samples/backups-delete.js +++ b/samples/backups-delete.js @@ -15,7 +15,7 @@ 'use strict'; -async function deleteBackup(instanceId, backupId, projectId) { +function main(instanceId, backupId, projectId) { // [START spanner_delete_backup] // Imports the Google Cloud client library @@ -38,22 +38,28 @@ async function deleteBackup(instanceId, backupId, projectId) { const databaseAdminClient = spanner.getDatabaseAdminClient(); // Delete the backup - console.log(`Deleting backup ${backupId}.`); - await databaseAdminClient.deleteBackup({ - name: databaseAdminClient.backupPath(projectId, instanceId, backupId), - }); - console.log('Backup deleted.'); - - // Verify backup no longer exists - try { - await databaseAdminClient.getBackup({ + async function deleteBackup() { + console.log(`Deleting backup ${backupId}.`); + await databaseAdminClient.deleteBackup({ name: databaseAdminClient.backupPath(projectId, instanceId, backupId), }); - console.error('Error: backup still exists.'); - } catch (err) { console.log('Backup deleted.'); + // Verify backup no longer exists + try { + await databaseAdminClient.getBackup({ + name: databaseAdminClient.backupPath(projectId, instanceId, backupId), + }); + console.error('Error: backup still exists.'); + } catch (err) { + console.log('Backup deleted.'); + } } + deleteBackup(); // [END spanner_delete_backup] } -module.exports.deleteBackup = deleteBackup; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups-get-database-operations.js b/samples/backups-get-database-operations.js index b4be6ffc0..07d584550 100644 --- a/samples/backups-get-database-operations.js +++ b/samples/backups-get-database-operations.js @@ -15,7 +15,7 @@ 'use strict'; -async function getDatabaseOperations(instanceId, projectId) { +function main(instanceId, projectId) { // [START spanner_list_database_operations] // Imports the Google Cloud client library @@ -36,28 +36,35 @@ async function getDatabaseOperations(instanceId, projectId) { const databaseAdminClient = spanner.getDatabaseAdminClient(); // List database operations - try { - const [databaseOperations] = - await databaseAdminClient.listDatabaseOperations({ - parent: databaseAdminClient.instancePath(projectId, instanceId), - filter: - '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)', - }); - console.log('Optimize Database Operations:'); - databaseOperations.forEach(databaseOperation => { - const metadata = - protos.google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata.decode( - databaseOperation.metadata.value + async function getDatabaseOperations() { + try { + const [databaseOperations] = + await databaseAdminClient.listDatabaseOperations({ + parent: databaseAdminClient.instancePath(projectId, instanceId), + filter: + '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)', + }); + console.log('Optimize Database Operations:'); + databaseOperations.forEach(databaseOperation => { + const metadata = + protos.google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata.decode( + databaseOperation.metadata.value + ); + console.log( + `Database ${metadata.name} restored from backup is ` + + `${metadata.progress.progressPercent}% optimized.` ); - console.log( - `Database ${metadata.name} restored from backup is ` + - `${metadata.progress.progressPercent}% optimized.` - ); - }); - } catch (err) { - console.error('ERROR:', err); + }); + } catch (err) { + console.error('ERROR:', err); + } } + getDatabaseOperations(); // [END spanner_list_database_operations] } -module.exports.getDatabaseOperations = getDatabaseOperations; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups-get-operations.js b/samples/backups-get-operations.js index ae6b2f8a4..cfbbfb228 100644 --- a/samples/backups-get-operations.js +++ b/samples/backups-get-operations.js @@ -15,12 +15,7 @@ 'use strict'; -async function getBackupOperations( - instanceId, - databaseId, - backupId, - projectId -) { +function main(instanceId, databaseId, backupId, projectId) { // [START spanner_list_backup_operations] // Imports the Google Cloud client library @@ -43,55 +38,65 @@ async function getBackupOperations( const databaseAdminClient = spanner.getDatabaseAdminClient(); // List create backup operations - try { - const [backupOperations] = await databaseAdminClient.listBackupOperations({ - parent: databaseAdminClient.instancePath(projectId, instanceId), - filter: - '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) ' + - `AND (metadata.database:${databaseId})`, - }); - console.log('Create Backup Operations:'); - backupOperations.forEach(backupOperation => { - const metadata = - protos.google.spanner.admin.database.v1.CreateBackupMetadata.decode( - backupOperation.metadata.value - ); - console.log( - `Backup ${metadata.name} on database ${metadata.database} is ` + - `${metadata.progress.progressPercent}% complete.` + async function getBackupOperations() { + try { + const [backupOperations] = await databaseAdminClient.listBackupOperations( + { + parent: databaseAdminClient.instancePath(projectId, instanceId), + filter: + '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) ' + + `AND (metadata.database:${databaseId})`, + } ); - }); - } catch (err) { - console.error('ERROR:', err); - } - - // List copy backup operations - try { - console.log( - '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) ' + - `AND (metadata.source_backup:${backupId})` - ); - const [backupOperations] = await databaseAdminClient.listBackupOperations({ - parent: databaseAdminClient.instancePath(projectId, instanceId), - filter: - '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) ' + - `AND (metadata.source_backup:${backupId})`, - }); - console.log('Copy Backup Operations:'); - backupOperations.forEach(backupOperation => { - const metadata = - protos.google.spanner.admin.database.v1.CopyBackupMetadata.decode( - backupOperation.metadata.value + console.log('Create Backup Operations:'); + backupOperations.forEach(backupOperation => { + const metadata = + protos.google.spanner.admin.database.v1.CreateBackupMetadata.decode( + backupOperation.metadata.value + ); + console.log( + `Backup ${metadata.name} on database ${metadata.database} is ` + + `${metadata.progress.progressPercent}% complete.` ); + }); + } catch (err) { + console.error('ERROR:', err); + } + // List copy backup operations + try { console.log( - `Backup ${metadata.name} copied from source backup ${metadata.sourceBackup} is ` + - `${metadata.progress.progressPercent}% complete.` + '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) ' + + `AND (metadata.source_backup:${backupId})` ); - }); - } catch (err) { - console.error('ERROR:', err); + const [backupOperations] = await databaseAdminClient.listBackupOperations( + { + parent: databaseAdminClient.instancePath(projectId, instanceId), + filter: + '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) ' + + `AND (metadata.source_backup:${backupId})`, + } + ); + console.log('Copy Backup Operations:'); + backupOperations.forEach(backupOperation => { + const metadata = + protos.google.spanner.admin.database.v1.CopyBackupMetadata.decode( + backupOperation.metadata.value + ); + console.log( + `Backup ${metadata.name} copied from source backup ${metadata.sourceBackup} is ` + + `${metadata.progress.progressPercent}% complete.` + ); + }); + } catch (err) { + console.error('ERROR:', err); + } } + getBackupOperations(); // [END spanner_list_backup_operations] } -module.exports.getBackupOperations = getBackupOperations; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups-get.js b/samples/backups-get.js index f5ab5416f..1d94781f9 100644 --- a/samples/backups-get.js +++ b/samples/backups-get.js @@ -15,7 +15,7 @@ 'use strict'; -async function getBackups(instanceId, databaseId, backupId, projectId) { +function main(instanceId, databaseId, backupId, projectId) { // [START spanner_list_backups] // Imports the Google Cloud client library @@ -37,129 +37,137 @@ async function getBackups(instanceId, databaseId, backupId, projectId) { // Gets a reference to a Cloud Spanner Database Admin Client object const databaseAdminClient = spanner.getDatabaseAdminClient(); - try { - // Get the parent(instance) of the database - const parent = databaseAdminClient.instancePath(projectId, instanceId); - - // List all backups - const [allBackups] = await databaseAdminClient.listBackups({ - parent: parent, - }); - - console.log('All backups:'); - allBackups.forEach(backups => { - if (backups.name) { - const backup = backups.name; - const delimiter = - 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; - const result = backup.substring(delimiter.length); - console.log(result); - } - }); - - // List backups filtered by backup name - const [backupsByName] = await databaseAdminClient.listBackups({ - parent: parent, - filter: `Name:${backupId}`, - }); - console.log('Backups matching backup name:'); - backupsByName.forEach(backup => { - if (backup.name) { - const backupName = backup.name; - const delimiter = - 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; - const result = backupName.substring(delimiter.length); - console.log(result); - } - }); - - // List backups expiring within 30 days - const expireTime = new Date(); - expireTime.setDate(expireTime.getDate() + 30); - const [backupsByExpiry] = await databaseAdminClient.listBackups({ - parent: parent, - filter: `expire_time < "${expireTime.toISOString()}"`, - }); - console.log('Backups expiring within 30 days:'); - backupsByExpiry.forEach(backup => { - if (backup.name) { - const backupName = backup.name; - const delimiter = - 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; - const result = backupName.substring(delimiter.length); - console.log(result); - } - }); - - // List backups filtered by database name - const [backupsByDbName] = await databaseAdminClient.listBackups({ - parent: parent, - filter: `Database:${databaseId}`, - }); - console.log('Backups matching database name:'); - backupsByDbName.forEach(backup => { - if (backup.name) { - const backupName = backup.name; - const delimiter = - 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; - const result = backupName.substring(delimiter.length); - console.log(result); - } - }); - - // List backups filtered by backup size - const [backupsBySize] = await databaseAdminClient.listBackups({ - parent: parent, - filter: 'size_bytes > 100', - }); - console.log('Backups filtered by size:'); - backupsBySize.forEach(backup => { - if (backup.name) { - const backupName = backup.name; - const delimiter = - 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; - const result = backupName.substring(delimiter.length); - console.log(result); - } - }); - - // List backups that are ready that were created after a certain time - const createTime = new Date(); - createTime.setDate(createTime.getDate() - 1); - const [backupsByCreateTime] = await databaseAdminClient.listBackups({ - parent: parent, - filter: `(state:READY) AND (create_time >= "${createTime.toISOString()}")`, - }); - console.log('Ready backups filtered by create time:'); - backupsByCreateTime.forEach(backup => { - if (backup.name) { - const backupName = backup.name; - const delimiter = - 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; - const result = backupName.substring(delimiter.length); - console.log(result); - } - }); - - // List backups using pagination - console.log('Get backups paginated:'); - const [backups] = await databaseAdminClient.listBackups({ - parent: parent, - pageSize: 3, - }); - backups.forEach(backup => { - if (backup.name) { - const backupName = backup.name; - const delimiter = - 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; - const result = backupName.substring(delimiter.length); - console.log(result); - } - }); - } catch (err) { - console.error('ERROR:', err); + async function getBackups() { + try { + // Get the parent(instance) of the database + const parent = databaseAdminClient.instancePath(projectId, instanceId); + + // List all backups + const [allBackups] = await databaseAdminClient.listBackups({ + parent: parent, + }); + + console.log('All backups:'); + allBackups.forEach(backups => { + if (backups.name) { + const backup = backups.name; + const delimiter = + 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; + const result = backup.substring(delimiter.length); + console.log(result); + } + }); + + // List backups filtered by backup name + const [backupsByName] = await databaseAdminClient.listBackups({ + parent: parent, + filter: `Name:${backupId}`, + }); + console.log('Backups matching backup name:'); + backupsByName.forEach(backup => { + if (backup.name) { + const backupName = backup.name; + const delimiter = + 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; + const result = backupName.substring(delimiter.length); + console.log(result); + } + }); + + // List backups expiring within 30 days + const expireTime = new Date(); + expireTime.setDate(expireTime.getDate() + 30); + const [backupsByExpiry] = await databaseAdminClient.listBackups({ + parent: parent, + filter: `expire_time < "${expireTime.toISOString()}"`, + }); + console.log('Backups expiring within 30 days:'); + backupsByExpiry.forEach(backup => { + if (backup.name) { + const backupName = backup.name; + const delimiter = + 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; + const result = backupName.substring(delimiter.length); + console.log(result); + } + }); + + // List backups filtered by database name + const [backupsByDbName] = await databaseAdminClient.listBackups({ + parent: parent, + filter: `Database:${databaseId}`, + }); + console.log('Backups matching database name:'); + backupsByDbName.forEach(backup => { + if (backup.name) { + const backupName = backup.name; + const delimiter = + 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; + const result = backupName.substring(delimiter.length); + console.log(result); + } + }); + + // List backups filtered by backup size + const [backupsBySize] = await databaseAdminClient.listBackups({ + parent: parent, + filter: 'size_bytes > 100', + }); + console.log('Backups filtered by size:'); + backupsBySize.forEach(backup => { + if (backup.name) { + const backupName = backup.name; + const delimiter = + 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; + const result = backupName.substring(delimiter.length); + console.log(result); + } + }); + + // List backups that are ready that were created after a certain time + const createTime = new Date(); + createTime.setDate(createTime.getDate() - 1); + const [backupsByCreateTime] = await databaseAdminClient.listBackups({ + parent: parent, + filter: `(state:READY) AND (create_time >= "${createTime.toISOString()}")`, + }); + console.log('Ready backups filtered by create time:'); + backupsByCreateTime.forEach(backup => { + if (backup.name) { + const backupName = backup.name; + const delimiter = + 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; + const result = backupName.substring(delimiter.length); + console.log(result); + } + }); + + // List backups using pagination + console.log('Get backups paginated:'); + const [backups] = await databaseAdminClient.listBackups({ + parent: parent, + pageSize: 3, + }); + backups.forEach(backup => { + if (backup.name) { + const backupName = backup.name; + const delimiter = + 'projects/' + projectId + '/instances/' + instanceId + '/backups/'; + const result = backupName.substring(delimiter.length); + console.log(result); + } + }); + } catch (err) { + console.error('ERROR:', err); + } } + + getBackups(); // [END spanner_list_backups] } -module.exports.getBackups = getBackups; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups-restore-with-encryption-key.js b/samples/backups-restore-with-encryption-key.js index 7a2323246..077f86e13 100644 --- a/samples/backups-restore-with-encryption-key.js +++ b/samples/backups-restore-with-encryption-key.js @@ -15,13 +15,7 @@ 'use strict'; -async function restoreBackupWithEncryptionKey( - instanceId, - databaseId, - backupId, - projectId, - keyName -) { +function main(instanceId, databaseId, backupId, projectId, keyName) { // [START spanner_restore_backup_with_encryption_key] // Imports the Google Cloud client library and precise date library @@ -46,37 +40,44 @@ async function restoreBackupWithEncryptionKey( const databaseAdminClient = spanner.getDatabaseAdminClient(); // Restore the database - console.log( - `Restoring database ${databaseAdminClient.databasePath( - projectId, - instanceId, - databaseId - )} from backup ${backupId}.` - ); - const [restoreOperation] = await databaseAdminClient.restoreDatabase({ - parent: databaseAdminClient.instancePath(projectId, instanceId), - databaseId: databaseId, - backup: databaseAdminClient.backupPath(projectId, instanceId, backupId), - encryptionConfig: { - encryptionType: 'CUSTOMER_MANAGED_ENCRYPTION', - kmsKeyName: keyName, - }, - }); + async function restoreBackupWithEncryptionKey() { + console.log( + `Restoring database ${databaseAdminClient.databasePath( + projectId, + instanceId, + databaseId + )} from backup ${backupId}.` + ); + const [restoreOperation] = await databaseAdminClient.restoreDatabase({ + parent: databaseAdminClient.instancePath(projectId, instanceId), + databaseId: databaseId, + backup: databaseAdminClient.backupPath(projectId, instanceId, backupId), + encryptionConfig: { + encryptionType: 'CUSTOMER_MANAGED_ENCRYPTION', + kmsKeyName: keyName, + }, + }); - // Wait for restore to complete - console.log('Waiting for database restore to complete...'); - await restoreOperation.promise(); + // Wait for restore to complete + console.log('Waiting for database restore to complete...'); + await restoreOperation.promise(); - console.log('Database restored from backup.'); - const [metadata] = await databaseAdminClient.getDatabase({ - name: databaseAdminClient.databasePath(projectId, instanceId, databaseId), - }); - console.log( - `Database ${metadata.restoreInfo.backupInfo.sourceDatabase} was restored ` + - `to ${databaseId} from backup ${metadata.restoreInfo.backupInfo.backup} ` + - `using encryption key ${metadata.encryptionConfig.kmsKeyName}.` - ); + console.log('Database restored from backup.'); + const [metadata] = await databaseAdminClient.getDatabase({ + name: databaseAdminClient.databasePath(projectId, instanceId, databaseId), + }); + console.log( + `Database ${metadata.restoreInfo.backupInfo.sourceDatabase} was restored ` + + `to ${databaseId} from backup ${metadata.restoreInfo.backupInfo.backup} ` + + `using encryption key ${metadata.encryptionConfig.kmsKeyName}.` + ); + } + restoreBackupWithEncryptionKey(); // [END spanner_restore_backup_with_encryption_key] } -module.exports.restoreBackupWithEncryptionKey = restoreBackupWithEncryptionKey; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups-restore.js b/samples/backups-restore.js index 182513479..cc98687b4 100644 --- a/samples/backups-restore.js +++ b/samples/backups-restore.js @@ -15,7 +15,7 @@ 'use strict'; -async function restoreBackup(instanceId, databaseId, backupId, projectId) { +function main(instanceId, databaseId, backupId, projectId) { // [START spanner_restore_backup] // Imports the Google Cloud client library and precise date library const {Spanner} = require('@google-cloud/spanner'); @@ -38,36 +38,43 @@ async function restoreBackup(instanceId, databaseId, backupId, projectId) { const databaseAdminClient = spanner.getDatabaseAdminClient(); // Restore the database - console.log( - `Restoring database ${databaseAdminClient.databasePath( - projectId, - instanceId, - databaseId - )} from backup ${backupId}.` - ); - const [restoreOperation] = await databaseAdminClient.restoreDatabase({ - parent: databaseAdminClient.instancePath(projectId, instanceId), - databaseId: databaseId, - backup: databaseAdminClient.backupPath(projectId, instanceId, backupId), - }); + async function restoreBackup() { + console.log( + `Restoring database ${databaseAdminClient.databasePath( + projectId, + instanceId, + databaseId + )} from backup ${backupId}.` + ); + const [restoreOperation] = await databaseAdminClient.restoreDatabase({ + parent: databaseAdminClient.instancePath(projectId, instanceId), + databaseId: databaseId, + backup: databaseAdminClient.backupPath(projectId, instanceId, backupId), + }); - // Wait for restore to complete - console.log('Waiting for database restore to complete...'); - await restoreOperation.promise(); + // Wait for restore to complete + console.log('Waiting for database restore to complete...'); + await restoreOperation.promise(); - console.log('Database restored from backup.'); - const [metadata] = await databaseAdminClient.getDatabase({ - name: databaseAdminClient.databasePath(projectId, instanceId, databaseId), - }); - console.log( - `Database ${metadata.restoreInfo.backupInfo.sourceDatabase} was restored ` + - `to ${databaseId} from backup ${metadata.restoreInfo.backupInfo.backup} ` + - 'with version time ' + - `${new PreciseDate( - metadata.restoreInfo.backupInfo.versionTime - ).toISOString()}.` - ); + console.log('Database restored from backup.'); + const [metadata] = await databaseAdminClient.getDatabase({ + name: databaseAdminClient.databasePath(projectId, instanceId, databaseId), + }); + console.log( + `Database ${metadata.restoreInfo.backupInfo.sourceDatabase} was restored ` + + `to ${databaseId} from backup ${metadata.restoreInfo.backupInfo.backup} ` + + 'with version time ' + + `${new PreciseDate( + metadata.restoreInfo.backupInfo.versionTime + ).toISOString()}.` + ); + } + restoreBackup(); // [END spanner_restore_backup] } -module.exports.restoreBackup = restoreBackup; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups-update.js b/samples/backups-update.js index 3bb540d4f..5062ed0c1 100644 --- a/samples/backups-update.js +++ b/samples/backups-update.js @@ -15,7 +15,7 @@ 'use strict'; -async function updateBackup(instanceId, backupId, projectId) { +function main(instanceId, backupId, projectId) { // [START spanner_update_backup] // Imports the Google Cloud client library and precise date library @@ -38,45 +38,52 @@ async function updateBackup(instanceId, backupId, projectId) { const databaseAdminClient = spanner.getDatabaseAdminClient(); // Read backup metadata and update expiry time - try { - const [metadata] = await databaseAdminClient.getBackup({ - name: databaseAdminClient.backupPath(projectId, instanceId, backupId), - }); + async function updateBackup() { + try { + const [metadata] = await databaseAdminClient.getBackup({ + name: databaseAdminClient.backupPath(projectId, instanceId, backupId), + }); - const currentExpireTime = metadata.expireTime; - const maxExpireTime = metadata.maxExpireTime; - const wantExpireTime = new PreciseDate(currentExpireTime); - wantExpireTime.setDate(wantExpireTime.getDate() + 1); + const currentExpireTime = metadata.expireTime; + const maxExpireTime = metadata.maxExpireTime; + const wantExpireTime = new PreciseDate(currentExpireTime); + wantExpireTime.setDate(wantExpireTime.getDate() + 1); - // New expire time should be less than the max expire time - const min = (currentExpireTime, maxExpireTime) => - currentExpireTime < maxExpireTime ? currentExpireTime : maxExpireTime; - const newExpireTime = new PreciseDate(min(wantExpireTime, maxExpireTime)); - console.log( - `Backup ${backupId} current expire time: ${Spanner.timestamp( - currentExpireTime - ).toISOString()}` - ); - console.log( - `Updating expire time to ${Spanner.timestamp( - newExpireTime - ).toISOString()}` - ); + // New expire time should be less than the max expire time + const min = (currentExpireTime, maxExpireTime) => + currentExpireTime < maxExpireTime ? currentExpireTime : maxExpireTime; + const newExpireTime = new PreciseDate(min(wantExpireTime, maxExpireTime)); + console.log( + `Backup ${backupId} current expire time: ${Spanner.timestamp( + currentExpireTime + ).toISOString()}` + ); + console.log( + `Updating expire time to ${Spanner.timestamp( + newExpireTime + ).toISOString()}` + ); - await databaseAdminClient.updateBackup({ - backup: { - name: databaseAdminClient.backupPath(projectId, instanceId, backupId), - expireTime: Spanner.timestamp(newExpireTime).toStruct(), - }, - updateMask: (protos.google.protobuf.FieldMask = { - paths: ['expire_time'], - }), - }); - console.log('Expire time updated.'); - } catch (err) { - console.error('ERROR:', err); + await databaseAdminClient.updateBackup({ + backup: { + name: databaseAdminClient.backupPath(projectId, instanceId, backupId), + expireTime: Spanner.timestamp(newExpireTime).toStruct(), + }, + updateMask: (protos.google.protobuf.FieldMask = { + paths: ['expire_time'], + }), + }); + console.log('Expire time updated.'); + } catch (err) { + console.error('ERROR:', err); + } } + updateBackup(); // [END spanner_update_backup] } -module.exports.updateBackup = updateBackup; +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/backups.js b/samples/backups.js deleted file mode 100644 index efec54cde..000000000 --- a/samples/backups.js +++ /dev/null @@ -1,168 +0,0 @@ -/** - * Copyright 2024 Google LLC - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const {createBackup} = require('./backups-create'); -const { - createBackupWithEncryptionKey, -} = require('./backups-create-with-encryption-key'); -const {cancelBackup} = require('./backups-cancel'); -const {getBackups} = require('./backups-get'); -const {getBackupOperations} = require('./backups-get-operations'); -const {getDatabaseOperations} = require('./backups-get-database-operations'); -const {updateBackup} = require('./backups-update'); -const {restoreBackup} = require('./backups-restore'); -const { - restoreBackupWithEncryptionKey, -} = require('./backups-restore-with-encryption-key'); -const {deleteBackup} = require('./backups-delete'); - -require('yargs') - .demand(1) - .command( - 'createBackup ', - 'Creates a backup of a Cloud Spanner database.', - {}, - opts => - createBackup( - opts.instanceName, - opts.databaseName, - opts.backupName, - opts.projectId, - Date.parse(opts.versionTime) - ) - ) - .example( - 'node $0 createBackup "my-instance" "my-database" "my-backup" "my-project-id" "my-version-time"' - ) - .command( - 'createBackupWithEncryptionKey ', - 'Creates a backup of a Cloud Spanner database using an encryption key.', - {}, - opts => - createBackupWithEncryptionKey( - opts.instanceName, - opts.databaseName, - opts.backupName, - opts.projectId, - opts.keyName - ) - ) - .example( - 'node $0 createBackupWithEncryptionKey "my-instance" "my-database" "my-backup" "my-project-id" "my-key-name"' - ) - .command( - 'cancelBackup ', - 'Creates and cancels a backup of a Cloud Spanner database.', - {}, - opts => - cancelBackup( - opts.instanceName, - opts.databaseName, - opts.backupName, - opts.projectId - ) - ) - .example( - 'node $0 cancelBackup "my-instance" "my-database" "my-backup" "my-project-id"' - ) - .command( - 'getBackups ', - 'Lists backups in the instance with filters.', - {}, - opts => - getBackups( - opts.instanceName, - opts.databaseName, - opts.backupName, - opts.projectId - ) - ) - .example( - 'node $0 getBackups "my-instance" "my-database" "my-backup" "my-project-id"' - ) - .command( - 'getBackupOperations ', - 'Lists all backup operations in the instance.', - {}, - opts => - getBackupOperations( - opts.instanceName, - opts.databaseName, - opts.backupName, - opts.projectId - ) - ) - .example( - 'node $0 getBackupOperations "my-instance" "my-database" "my-backup" "my-project-id"' - ) - .command( - 'getDatabaseOperations ', - 'Lists all database operations in the instance.', - {}, - opts => getDatabaseOperations(opts.instanceName, opts.projectId) - ) - .example('node $0 getDatabaseOperations "my-instance" "my-project-id"') - .command( - 'updateBackup ', - 'Updates the expire time of a backup.', - {}, - opts => updateBackup(opts.instanceName, opts.backupName, opts.projectId) - ) - .example('node $0 updateBackup "my-instance" "my-backup" "my-project-id"') - .command( - 'restoreBackup ', - 'Restores a Cloud Spanner database from a backup.', - {}, - opts => - restoreBackup( - opts.instanceName, - opts.databaseName, - opts.backupName, - opts.projectId - ) - ) - .example( - 'node $0 restoreBackup "my-instance" "my-database" "my-backup" "my-project-id"' - ) - .command( - 'restoreBackupWithEncryptionKey ', - 'Restores a Cloud Spanner database from a backup with an encryption key.', - {}, - opts => - restoreBackupWithEncryptionKey( - opts.instanceName, - opts.databaseName, - opts.backupName, - opts.projectId, - opts.keyName - ) - ) - .example( - 'node $0 restoreBackupWithEncryptionKey "my-instance" "my-database" "my-backup" "my-project-id" "my-key-name"' - ) - .command( - 'deleteBackup ', - 'Deletes a backup.', - {}, - opts => deleteBackup(opts.instanceName, opts.backupName, opts.projectId) - ) - .example('node $0 deleteBackup "my-instance" "my-backup" "my-project-id"') - .wrap(120) - .recommendCommands() - .epilogue('For more information, see https://cloud.google.com/spanner/docs') - .strict() - .help().argv; diff --git a/samples/system-test/spanner.test.js b/samples/system-test/spanner.test.js index 384e3fc58..2e9618691 100644 --- a/samples/system-test/spanner.test.js +++ b/samples/system-test/spanner.test.js @@ -42,7 +42,6 @@ const structCmd = 'node struct.js'; const dmlCmd = 'node dml.js'; const batchWriteCmd = 'node batch-write.js'; const datatypesCmd = 'node datatypes.js'; -const backupsCmd = 'node backups.js'; const instanceCmd = 'node instance.js'; const createTableWithForeignKeyDeleteCascadeCommand = 'node table-create-with-foreign-key-delete-cascade.js'; @@ -1331,7 +1330,7 @@ describe('Autogenerated Admin Clients', () => { const versionTime = rows[0].toJSON().Timestamp.toISOString(); const output = execSync( - `${backupsCmd} createBackup ${INSTANCE_ID} ${DATABASE_ID} ${BACKUP_ID} ${PROJECT_ID} ${versionTime}` + `node backups-create ${INSTANCE_ID} ${DATABASE_ID} ${BACKUP_ID} ${PROJECT_ID} ${versionTime}` ); assert.match(output, new RegExp(`Backup (.+)${BACKUP_ID} of size`)); }); @@ -1341,7 +1340,7 @@ describe('Autogenerated Admin Clients', () => { const key = await getCryptoKey(); const output = execSync( - `${backupsCmd} createBackupWithEncryptionKey ${INSTANCE_ID} ${DATABASE_ID} ${ENCRYPTED_BACKUP_ID} ${PROJECT_ID} ${key.name}` + `node backups-create-with-encryption-key ${INSTANCE_ID} ${DATABASE_ID} ${ENCRYPTED_BACKUP_ID} ${PROJECT_ID} ${key.name}` ); assert.match( output, @@ -1365,7 +1364,7 @@ describe('Autogenerated Admin Clients', () => { // cancel_backup it('should cancel a backup of the database', async () => { const output = execSync( - `${backupsCmd} cancelBackup ${INSTANCE_ID} ${DATABASE_ID} ${CANCELLED_BACKUP_ID} ${PROJECT_ID}` + `node backups-cancel ${INSTANCE_ID} ${DATABASE_ID} ${CANCELLED_BACKUP_ID} ${PROJECT_ID}` ); assert.match(output, /Backup cancelled./); }); @@ -1373,7 +1372,7 @@ describe('Autogenerated Admin Clients', () => { // get_backups it('should list backups in the instance', async () => { const output = execSync( - `${backupsCmd} getBackups ${INSTANCE_ID} ${DATABASE_ID} ${BACKUP_ID} ${PROJECT_ID}` + `node backups-get ${INSTANCE_ID} ${DATABASE_ID} ${BACKUP_ID} ${PROJECT_ID}` ); assert.include(output, 'All backups:'); assert.include(output, 'Backups matching backup name:'); @@ -1389,7 +1388,7 @@ describe('Autogenerated Admin Clients', () => { // list_backup_operations it('should list backup operations in the instance', async () => { const output = execSync( - `${backupsCmd} getBackupOperations ${INSTANCE_ID} ${DATABASE_ID} ${BACKUP_ID} ${PROJECT_ID}` + `node backups-get-operations ${INSTANCE_ID} ${DATABASE_ID} ${BACKUP_ID} ${PROJECT_ID}` ); assert.match(output, /Create Backup Operations:/); assert.match( @@ -1406,7 +1405,7 @@ describe('Autogenerated Admin Clients', () => { // update_backup_expire_time it('should update the expire time of a backup', async () => { const output = execSync( - `${backupsCmd} updateBackup ${INSTANCE_ID} ${BACKUP_ID} ${PROJECT_ID}` + `node backups-update ${INSTANCE_ID} ${BACKUP_ID} ${PROJECT_ID}` ); assert.match(output, /Expire time updated./); }); @@ -1420,7 +1419,7 @@ describe('Autogenerated Admin Clients', () => { await delay(this.test); const output = execSync( - `${backupsCmd} restoreBackup ${INSTANCE_ID} ${RESTORE_DATABASE_ID} ${BACKUP_ID} ${PROJECT_ID}` + `node backups-restore ${INSTANCE_ID} ${RESTORE_DATABASE_ID} ${BACKUP_ID} ${PROJECT_ID}` ); assert.match(output, /Database restored from backup./); assert.match( @@ -1443,7 +1442,7 @@ describe('Autogenerated Admin Clients', () => { const key = await getCryptoKey(); const output = execSync( - `${backupsCmd} restoreBackupWithEncryptionKey ${INSTANCE_ID} ${ENCRYPTED_RESTORE_DATABASE_ID} ${ENCRYPTED_BACKUP_ID} ${PROJECT_ID} ${key.name}` + `node backups-restore-with-encryption-key ${INSTANCE_ID} ${ENCRYPTED_RESTORE_DATABASE_ID} ${ENCRYPTED_BACKUP_ID} ${PROJECT_ID} ${key.name}` ); assert.match(output, /Database restored from backup./); assert.match( @@ -1458,7 +1457,7 @@ describe('Autogenerated Admin Clients', () => { // list_database_operations it('should list database operations in the instance', async () => { const output = execSync( - `${backupsCmd} getDatabaseOperations ${INSTANCE_ID} ${PROJECT_ID}` + `node backups-get-database-operations ${INSTANCE_ID} ${PROJECT_ID}` ); assert.match(output, /Optimize Database Operations:/); assert.match( @@ -1484,7 +1483,7 @@ describe('Autogenerated Admin Clients', () => { } const output = execSync( - `${backupsCmd} deleteBackup ${INSTANCE_ID} ${BACKUP_ID} ${PROJECT_ID}` + `node backups-delete ${INSTANCE_ID} ${BACKUP_ID} ${PROJECT_ID}` ); assert.match(output, /Backup deleted./); });