Utilizzo di Node.js V2

Il sito IBM Cloud® Object Storage SDK for Node.js v2 offre funzionalità che consentono di sfruttare al meglio IBM Cloud Object Storage.

Il sito IBM Cloud Object Storage SDK for Node.js v2 è molto completo e offre numerose funzionalità e possibilità che vanno ben oltre l'ambito e lo spazio di questa guida. Per una documentazione dettagliata sulle classi e sui metodi, consultare la documentazione di riferimento dell'API di Node.js. Il codice sorgente è disponibile nel repository GitHub.

Novità in v2

IBM Cloud Object Storage SDK for Node.js v2 è una versione modernizzata basata sull'architettura dell'SDK AWS v3, che apporta miglioramenti significativi:

  • Architettura modulare- Importa solo i comandi e i client di cui hai bisogno
  • Progettazione "Promise-first " - Supporto nativo di async/await con una gestione degli errori più chiara
  • Dimensioni dei pacchetti più ridotte: i moduli "tree-shakeable" riducono le dimensioni dell'applicazione
  • JavaScript e moderna- Sfrutta le funzionalità di ES6+ e il supporto di TypeScript
  • Stack middleware- Pipeline estensibile di richiesta/risposta
  • Migliore gestione degli errori- Tipi di errore strutturati con informazioni dettagliate

Gli sviluppatori che intendono effettuare la migrazione da v1 sono invitati a consultare la Guida alla migrazione.

Ottenimento dell'SDK

Il metodo consigliato per installare il sistema operativo IBM (COS) SDK for Node.js è quello di utilizzare il gestore di pacchetti npm per Node.js. È sufficiente digitare quanto segue in una finestra di terminale:

npm install ibm-cos-sdk-v2

Prerequisiti

  • Node.js 18 o versioni successive- L'SDK richiede almeno la versione 18 di Node.js o una versione successiva.
  • Un'istanza di IBM Cloud Object Storage
  • Una chiave API proveniente da IBM Cloud Identity and Access Management con almeno i permessi Writer
  • L'ID dell'istanza di COS con cui stai lavorando
  • Endpoint per l'acquisizione dei token
  • Endpoint del servizio

Questi valori sono disponibili nella console IBM Cloud generando una "credenziale di servizio".

Importa pacchetti

Dopo aver installato l'SDK, per poterlo utilizzare dovrai importare i pacchetti necessari nelle tue applicazioni Node.js, come illustrato nell'esempio seguente:

CommonJS:

const { S3Client } = require('ibm-cos-sdk-v2');
const {
  CreateBucketCommand,
  ListBucketsCommand,
  PutObjectCommand,
  GetObjectCommand
} = require('ibm-cos-sdk-v2');

Moduli ES / TypeScript:

import { S3Client } from 'ibm-cos-sdk-v2';
import {
  CreateBucketCommand,
  ListBucketsCommand,
  PutObjectCommand,
  GetObjectCommand
} from 'ibm-cos-sdk-v2';

Riferimenti SDK

Corsi fondamentali

  • S3Client- Client principale per l'interazione con IBM Cloud Object Storage
  • Classi di comando- Ad ogni operazione corrisponde una classe di comando (ad esempio, PutObjectCommand, GetObjectCommand)

Configurazione

  • S3Client costruttore- Crea un nuovo client S3 con opzioni di configurazione
  • regione- Imposta la regione per il cliente
  • endpoint- Imposta l'endpoint del servizio URL
  • credenziali- Imposta le credenziali di autenticazione

Creazione di un cliente e acquisizione delle credenziali del servizio

Per stabilire una connessione a IBM Cloud Object Storage, un client viene creato e configurato fornendo le informazioni delle credenziali (chiave API e ID istanza del servizio). Questi valori possono anche essere derivati automaticamente da un file di credenziali o dalle variabili di ambiente.

Le credenziali possono essere trovate creando una credenziale del servizio o tramite la CLI.

Utilizzo dell'autenticazione IAM di IBM

L'esempio seguente illustra come creare un client utilizzando l'autenticazione IAM di IBM con una chiave API:

CommonJS:

const { S3Client } = require('ibm-cos-sdk-v2');
// Initialize client
const client = new S3Client({
  endpoint: 'https://s3.us-south.cloud-object-storage.appdomain.cloud',
  region: 'us-south',
  credentials: {
    apiKey: '<API_KEY>',
    serviceInstanceId: '<SERVICE_INSTANCE_ID>'
  }
});

TypeScript:

import { S3Client } from 'ibm-cos-sdk-v2';
const client = new S3Client({
  endpoint: 'https://s3.us-south.cloud-object-storage.appdomain.cloud',
  region: 'us-south',
  credentials: {
    apiKey: '<API_KEY>',
    serviceInstanceId: '<SERVICE_INSTANCE_ID>'
  }
});

Le opzioni di configurazione richieste sono:

  • endpoint- L'endpoint URL relativo alla regione del tuo bucket COS
  • region- La regione in cui si trova il tuo bucket
  • credentials.apiKey- La tua chiave API di IBM Cloud con le autorizzazioni appropriate
  • credentials.serviceInstanceId- Il CRN (Cloud Resource Name) della tua istanza COS

Esempi di codici

Gli esempi che seguono presuppongono che abbiate già creato un cliente come illustrato nella sezione precedente.

Creazione di un bucket

const { CreateBucketCommand } = require('ibm-cos-sdk-v2');
const command = new CreateBucketCommand({
  Bucket: 'my-new-bucket',
  CreateBucketConfiguration: {
    LocationConstraint: 'us-south-standard'
  }
});
try {
  const response = await client.send(command);
  console.log('Bucket created successfully');
} catch (err) {
  console.error('Error creating bucket:', err);
}

Elenco dei bucket disponibili

const { ListBucketsCommand } = require('ibm-cos-sdk-v2');
try {
  const command = new ListBucketsCommand({});
  const response = await client.send(command);
  console.log('Buckets:');
  if (response.Buckets && response.Buckets.length > 0) {
    response.Buckets.forEach(bucket => {
      console.log(` - ${bucket.Name} (created: ${bucket.CreationDate})`);
    });
  } else {
    console.log(' No buckets found');
  }
} catch (err) {
  console.error('Failed to list buckets:', err);
}

Elenco dei bucket con informazioni dettagliate

IBM Cloud Object Storage fornisce un'operazione di elenco estesa che restituisce ulteriori informazioni sul bucket:

const { ListBucketsExtendedCommand } = require('ibm-cos-sdk-v2');
const command = new ListBucketsExtendedCommand({
  IBMServiceInstanceId: '<SERVICE_INSTANCE_ID>',
  Prefix: 'my-bucket-prefix',
  MaxKeys: 100
});
try {
  const response = await client.send(command);
  console.log('Extended Bucket Information:');
  if (response.Buckets && response.Buckets.length > 0) {
    response.Buckets.forEach(bucket => {
      console.log(` Bucket: ${bucket.Name}`);
      console.log(` Location: ${bucket.LocationConstraint}`);
      console.log(` Created: ${bucket.CreationDate}`);
    });
  } else {
    console.log(' No buckets found');
  }
} catch (err) {
  console.error('Failed to list buckets:', err);
}

Recupero della posizione di un bucket

const { GetBucketLocationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new GetBucketLocationCommand({
  Bucket: bucketName
});
try {
  const response = await client.send(command);
  console.log(`Bucket '${bucketName}' is located in: ${response.LocationConstraint}`);
} catch (err) {
  console.error('Failed to get bucket location:', err);
}

Eliminazione di un bucket

const { DeleteBucketCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket-to-delete';
const command = new DeleteBucketCommand({
  Bucket: bucketName
});
try {
  await client.send(command);
  console.log(`Bucket '${bucketName}' deleted successfully`);
} catch (err) {
  console.error('Failed to delete bucket:', err);
}

Nota: un bucket deve essere vuoto prima di poter essere eliminato.

Caricamento di un oggetto in un bucket

const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const content = 'Hello, IBM Cloud Object Storage!';
const command = new PutObjectCommand({
  Bucket: bucketName,
  Key: objectKey,
  Body: content
});
try {
  const response = await client.send(command);
  console.log(`Object '${objectKey}' uploaded successfully`);
  console.log(`ETag: ${response.ETag}`);
} catch (err) {
  console.error('Failed to upload object:', err);
}

Scaricare un oggetto da un bucket

const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new GetObjectCommand({
  Bucket: bucketName,
  Key: objectKey
});
try {
  const response = await client.send(command);
  // Convert stream to buffer
  const chunks = [];
  for await (const chunk of response.Body) {
    chunks.push(chunk);
  }
  const buffer = Buffer.concat(chunks);
  console.log(`Object '${objectKey}' downloaded successfully`);
  console.log(`Content-Type: ${response.ContentType}`);
  console.log(`Content-Length: ${response.ContentLength} bytes`);
  console.log(`Size: ${buffer.length} bytes`);
} catch (err) {
  console.error('Failed to download object:', err);
}

Elenco degli oggetti presenti in un bucket

const { ListObjectsV2Command } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListObjectsV2Command({
  Bucket: bucketName,
  MaxKeys: 1000
});
try {
  const response = await client.send(command);
  console.log(`Objects in bucket '${bucketName}':`);
  if (response.Contents && response.Contents.length > 0) {
    response.Contents.forEach(object => {
      console.log(` - ${object.Key} (size: ${object.Size} bytes, modified: ${object.LastModified})`);
    });
    console.log(`\nTotal objects: ${response.Contents.length}`);
  } else {
    console.log(' No objects found');
  }
} catch (err) {
  console.error('Failed to list objects:', err);
}

Copia di un oggetto

const { CopyObjectCommand } = require('ibm-cos-sdk-v2');
const sourceBucket = 'source-bucket';
const sourceKey = 'source-object.txt';
const destinationBucket = 'destination-bucket';
const destinationKey = 'destination-object.txt';
// CopySource format: source-bucket/source-key
const copySource = `${sourceBucket}/${sourceKey}`;
const command = new CopyObjectCommand({
  Bucket: destinationBucket,
  Key: destinationKey,
  CopySource: copySource
});
try {
  const response = await client.send(command);
  console.log('Object copied successfully');
  if (response.CopyObjectResult) {
    console.log(`ETag: ${response.CopyObjectResult.ETag}`);
  }
} catch (err) {
  console.error('Failed to copy object:', err);
}

Eliminazione di un oggetto

const { DeleteObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'object-to-delete.txt';
const command = new DeleteObjectCommand({
  Bucket: bucketName,
  Key: objectKey
});
try {
  await client.send(command);
  console.log(`Object '${objectKey}' deleted successfully`);
} catch (err) {
  console.error('Failed to delete object:', err);
}

Eliminazione di più oggetti

const { DeleteObjectsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectsToDelete = [
  'object1.txt',
  'object2.txt',
  'object3.txt'
];
// Build delete request
const objects = objectsToDelete.map(key => ({ Key: key }));
const command = new DeleteObjectsCommand({
  Bucket: bucketName,
  Delete: {
    Objects: objects,
    Quiet: false
  }
});
try {
  const response = await client.send(command);
  console.log('Delete operation completed');
  if (response.Deleted && response.Deleted.length > 0) {
    console.log(`Successfully deleted ${response.Deleted.length} object(s):`);
    response.Deleted.forEach(deleted => {
      console.log(` - ${deleted.Key}`);
    });
  }
  if (response.Errors && response.Errors.length > 0) {
    console.log(`\nFailed to delete ${response.Errors.length} object(s):`);
    response.Errors.forEach(error => {
      console.log(` - ${error.Key}: ${error.Message}`);
    });
  }
} catch (err) {
  console.error('Failed to delete objects:', err);
}

Recupero dei metadati di un oggetto (HEAD)

const { HeadObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new HeadObjectCommand({
  Bucket: bucketName,
  Key: objectKey
});
try {
  const response = await client.send(command);
  console.log(`Object Metadata for '${objectKey}':`);
  console.log(` Content-Type: ${response.ContentType}`);
  console.log(` Content-Length: ${response.ContentLength} bytes`);
  console.log(` ETag: ${response.ETag}`);
  console.log(` Last-Modified: ${response.LastModified}`);
  if (response.Metadata && Object.keys(response.Metadata).length > 0) {
    console.log(' Custom Metadata:');
    for (const [key, value] of Object.entries(response.Metadata)) {
      console.log(`  ${key}: ${value}`);
    }
  }
} catch (err) {
  console.error('Failed to get object metadata:', err);
}

Utilizzo di caricamenti in più parti

Per gli oggetti di grandi dimensioni, il caricamento in più parti garantisce una maggiore velocità di trasmissione e la possibilità di riprendere il caricamento. Ogni parte deve avere una dimensione minima di 5 MB (ad eccezione dell'ultima parte).

Caricamento manuale di file multipli:

const {
  CreateMultipartUploadCommand,
  UploadPartCommand,
  CompleteMultipartUploadCommand,
  AbortMultipartUploadCommand
} = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'large-object.dat';
try {
  // Step 1: Initiate multipart upload
  const createCommand = new CreateMultipartUploadCommand({
    Bucket: bucketName,
    Key: objectKey
  });
  const createResponse = await client.send(createCommand);
  const uploadId = createResponse.UploadId;
  console.log(`Multipart upload initiated with ID: ${uploadId}`);
  // Step 2: Upload parts (minimum 5MB per part except last)
  const completedParts = [];
  const minPartSize = 5 * 1024 * 1024; // 5MB
  // Create sample parts
  const parts = [
    'A'.repeat(minPartSize),
    'B'.repeat(minPartSize)
  ];
  for (let i = 0; i < parts.length; i++) {
    const partNumber = i + 1;
    const uploadPartCommand = new UploadPartCommand({
      Bucket: bucketName,
      Key: objectKey,
      PartNumber: partNumber,
      UploadId: uploadId,
      Body: parts[i]
    });
    try {
      const uploadResponse = await client.send(uploadPartCommand);
      completedParts.push({
        ETag: uploadResponse.ETag,
        PartNumber: partNumber
      });
      console.log(`Part ${partNumber} uploaded (ETag: ${uploadResponse.ETag})`);
    } catch (err) {
      // Abort multipart upload on error
      const abortCommand = new AbortMultipartUploadCommand({
        Bucket: bucketName,
        Key: objectKey,
        UploadId: uploadId
      });
      await client.send(abortCommand);
      throw err;
    }
  }
  // Step 3: Complete multipart upload
  const completeCommand = new CompleteMultipartUploadCommand({
    Bucket: bucketName,
    Key: objectKey,
    UploadId: uploadId,
    MultipartUpload: {
      Parts: completedParts
    }
  });
  const completeResponse = await client.send(completeCommand);
  console.log('Multipart upload completed successfully');
  console.log(`Location: ${completeResponse.Location}`);
  console.log(`ETag: ${completeResponse.ETag}`);
} catch (err) {
  console.error('Failed to complete multipart upload:', err);
}

Utilizzo di Upload Manager (consigliato):

Per semplificare il caricamento di file in più parti, utilizza il pacchetto @ibm-cos/lib-storage:

const { Upload } = require('@ibm-cos/lib-storage');
const { S3Client } = require('ibm-cos-sdk-v2');
const fs = require('fs');
const fileStream = fs.createReadStream('large-file.bin');
const upload = new Upload({
  client: client,
  params: {
    Bucket: 'my-bucket',
    Key: 'large-file.bin',
    Body: fileStream
  },
  queueSize: 4, // Concurrent parts
  partSize: 5 * 1024 * 1024, // 5MB parts
  leavePartsOnError: false
});
// Track progress
upload.on('httpUploadProgress', (progress) => {
  console.log('Upload progress:', progress);
});
try {
  const result = await upload.done();
  console.log('Upload completed:', result);
} catch (err) {
  console.error('Upload failed:', err);
}

Elenco dei caricamenti in più parti

const { ListMultipartUploadsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListMultipartUploadsCommand({
  Bucket: bucketName
});
try {
  const response = await client.send(command);
  console.log(`In-progress multipart uploads in bucket '${bucketName}':`);
  if (response.Uploads && response.Uploads.length > 0) {
    response.Uploads.forEach(upload => {
      console.log(` Key: ${upload.Key}`);
      console.log(` Upload ID: ${upload.UploadId}`);
      console.log(` Initiated: ${upload.Initiated}`);
    });
  } else {
    console.log(' No in-progress uploads found');
  }
} catch (err) {
  console.error('Failed to list multipart uploads:', err);
}

Elenco delle parti di un upload composto da più parti

Elenca tutti i file caricati relativi a un caricamento multiparte in corso. Utile per verificare lo stato di avanzamento o per raccogliere gli ETag prima di completare il caricamento.

const { ListPartsCommand } = require('ibm-cos-sdk-v2');
const command = new ListPartsCommand({
  Bucket: 'my-bucket',
  Key: 'my-large-object',
  UploadId: 'YOUR_UPLOAD_ID_HERE'
});
try {
  const response = await client.send(command);
  console.log('Parts listed successfully');
  if (response.Parts && response.Parts.length > 0) {
    response.Parts.forEach(p =>
      console.log(' - Part', p.PartNumber, '| ETag:', p.ETag, '| Size:', p.Size, 'bytes')
    );
  } else {
    console.log('No parts found.');
  }
} catch (err) {
  console.error('Error listing parts:', err);
}

Copia di una parte da un oggetto esistente

Carica una parte copiandola da un oggetto esistente. Utilizza questa opzione invece di caricare byte grezzi quando i dati di origine sono già presenti in COS.

const { UploadPartCopyCommand } = require('ibm-cos-sdk-v2');
const command = new UploadPartCopyCommand({
  Bucket: 'my-bucket',
  Key: 'my-large-object',
  UploadId: 'YOUR_UPLOAD_ID_HERE',
  PartNumber: 1,
  CopySource: 'my-bucket/source-object-key'
});
try {
  const response = await client.send(command);
  console.log('Part copy uploaded successfully');
  console.log('ETag:', response.CopyPartResult?.ETag);
} catch (err) {
  console.error('Error uploading part copy:', err);
}

Configurazione del ciclo di vita di un bucket

Le politiche di archiviazione consentono di trasferire automaticamente gli oggetti alle classi di archiviazione dopo un periodo di tempo specificato:

const { PutBucketLifecycleConfigurationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
// Configure lifecycle rule to expire objects after 30 days
const command = new PutBucketLifecycleConfigurationCommand({
  Bucket: bucketName,
  LifecycleConfiguration: {
    Rules: [
      {
        Id: 'delete-old-logs',
        Status: 'Enabled',
        Filter: {
          Prefix: 'logs/',
        },
        Expiration: {
          Days: 30,
        },
      },
      {
        Id: 'cleanup-multipart-uploads',
        Status: 'Enabled',
        Filter: {
          Prefix: '',
        },
        AbortIncompleteMultipartUpload: {
          DaysAfterInitiation: 7,
        },
      },
    ]
  }
});
try {
  await client.send(command);
  console.log(`Lifecycle configuration set for bucket '${bucketName}'`);
} catch (err) {
  console.error('Failed to set lifecycle configuration:', err);
}

Ottenere una configurazione del ciclo di vita di un bucket

const { GetBucketLifecycleConfigurationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new GetBucketLifecycleConfigurationCommand({
  Bucket: bucketName
});
try {
  const response = await client.send(command);
  console.log(`Lifecycle rules for bucket '${bucketName}':`);
  if (response.Rules && response.Rules.length > 0) {
    response.Rules.forEach(rule => {
      console.log(` Rule ID: ${rule.ID}`);
      console.log(` Status: ${rule.Status}`);
      if (rule.Transitions && rule.Transitions.length > 0) {
        rule.Transitions.forEach(transition => {
          console.log(` Transition to ${transition.StorageClass} after ${transition.Days} days`);
        });
      }
    });
  } else {
    console.log(' No lifecycle rules found');
  }
} catch (err) {
  console.error('Failed to get lifecycle configuration:', err);
}

Abilitazione del controllo delle versioni dei bucket

const { PutBucketVersioningCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new PutBucketVersioningCommand({
  Bucket: bucketName,
  VersioningConfiguration: {
    // Valid values: 'Enabled' | 'Suspended'
    Status: 'Enabled',
  },
});
try {
  await client.send(command);
  console.log(`Versioning enabled for bucket '${bucketName}'`);
} catch (err) {
  console.error('Failed to enable versioning:', err);
}

Elenco delle versioni degli oggetti

const { ListObjectVersionsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListObjectVersionsCommand({
  Bucket: bucketName
});
try {
  const response = await client.send(command);
  console.log(`Object versions in bucket '${bucketName}':`);
  if (response.Versions && response.Versions.length > 0) {
    response.Versions.forEach(version => {
      console.log(` Key: ${version.Key}`);
      console.log(` Version ID: ${version.VersionId}`);
      console.log(` Is Latest: ${version.IsLatest}`);
      console.log(` Last Modified: ${version.LastModified}`);
    });
  } else {
    console.log(' No versions found');
  }
} catch (err) {
  console.error('Failed to list object versions:', err);
}

Impostazione della configurazione di CORS

const { PutBucketCorsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
// Set CORS configuration
const command = new PutBucketCorsCommand({
  Bucket: bucketName,
  CORSConfiguration: {
    CORSRules: [
      {
        AllowedHeaders: ['*'],
        AllowedMethods: ['GET', 'PUT', 'POST', 'DELETE'],
        AllowedOrigins: ['https://example.com'],
        ExposeHeaders: ['ETag'],
        MaxAgeSeconds: 3000
      }
    ]
  }
});
try {
  await client.send(command);
  console.log(`CORS configuration set for bucket '${bucketName}'`);
} catch (err) {
  console.error('Failed to set CORS configuration:', err);
}

Impostazione dell'assegnazione di tag agli oggetti

const { PutObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
// Set object tags
const command = new PutObjectTaggingCommand({
  Bucket: bucketName,
  Key: objectKey,
  Tagging: {
    TagSet: [
      {
        Key: 'Department',
        Value: 'Finance'
      },
      {
        Key: 'Project',
        Value: 'Q4-2024'
      },
      {
        Key: 'Classification',
        Value: 'Confidential'
      }
    ]
  }
});
try {
  await client.send(command);
  console.log(`Tags set for object '${objectKey}'`);
} catch (err) {
  console.error('Failed to set object tags:', err);
}

Ottenere i tag degli oggetti

const { GetObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new GetObjectTaggingCommand({
  Bucket: bucketName,
  Key: objectKey
});
try {
  const response = await client.send(command);
  console.log(`Tags for object '${objectKey}':`);
  if (response.TagSet && response.TagSet.length > 0) {
    response.TagSet.forEach(tag => {
      console.log(` ${tag.Key}: ${tag.Value}`);
    });
  } else {
    console.log(' No tags found');
  }
} catch (err) {
  console.error('Failed to get object tags:', err);
}

Ripristino di un oggetto archiviato

Gli oggetti presenti nelle classi di archiviazione devono essere ripristinati prima di poter essere consultati:

const command = new RestoreObjectCommand({
  Bucket: bucketName,
  Key: objectKey,
  RestoreRequest: {
    Days: 7,
    GlacierJobParameters: {
      Tier: 'Bulk',
    },
  },
});
try {
  await client.send(command);
  console.log('Object restore initiated successfully');
  console.log(
    'Retrieval time depends on storage class: Vault typically 1-5 hours, Cold Vault typically 5-12 hours.'
  );
} catch (err) {
  console.error('Failed to restore object:', err);
}

Nota: IBM Cloud Object Storage supporta esclusivamente il livello di recupero " Bulk " per il ripristino di oggetti dalle classi di archiviazione "Vault" e "Cold Vault".

Impostazione della durata di conservazione degli oggetti

Modalità di gestione: gli utenti in possesso di specifiche autorizzazioni IAM possono eliminare le versioni degli oggetti durante il periodo di conservazione.

Modalità di conformità: nessun utente può eliminare le versioni degli oggetti durante il periodo di conservazione.

const { PutObjectRetentionCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-protected-bucket';
const objectKey = 'important-document.pdf';
// Set retention until a specific date
const retainUntil = new Date();
retainUntil.setDate(retainUntil.getDate() + 30);
const command = new PutObjectRetentionCommand({
  Bucket: bucketName,
  Key: objectKey,
  Retention: {
    Mode: 'COMPLIANCE',
    RetainUntilDate: retainUntil,
  },
});
try {
  await client.send(command);
  console.log('Object retention set successfully');
  console.log('RetainUntil:', retainUntil.toISOString());
} catch (err) {
  console.error('Error:', err.message);
}

Ottenere la ritenzione degli oggetti

const { GetObjectRetentionCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-protected-bucket';
const objectKey = 'important-document.pdf';
const command = new GetObjectRetentionCommand({
  Bucket: bucketName,
  Key: objectKey
});
try {
  const response = await client.send(command);
  console.log('Object retention retrieved successfully');
  console.log('Mode:', response.Retention?.Mode);
  console.log('RetainUntilDate:', response.Retention?.RetainUntilDate);
} catch (err) {
  console.error('Error:', err.message);
}

Creazione di un bucket con Object Lock ( S3 )

S3 Object Lock impedisce che gli oggetti vengano eliminati o sovrascritti per un periodo di conservazione prestabilito o a tempo indeterminato. Object Lock deve essere abilitato al momento della creazione del bucket: non è possibile aggiungerlo a un bucket esistente.

Modalità di gestione: gli utenti in possesso di specifiche autorizzazioni IAM possono eliminare le versioni degli oggetti durante il periodo di conservazione.

Modalità di conformità: nessun utente può eliminare le versioni degli oggetti durante il periodo di conservazione.

Questa sezione tratta di “ S3-compatible ” e “Object Lock”. Per informazioni sulla protezione WORM specifica per COS ( IBM ), consultare le sezioni " Impostazione della protezione dei bucket(WORM) " e " Gestione dei blocchi legali ".

const {
  CreateBucketCommand,
  PutObjectLockConfigurationCommand
} = require('ibm-cos-sdk-v2');
// Step 1: Create bucket with Object Lock enabled
const createCommand = new CreateBucketCommand({
  Bucket: 'my-locked-bucket',
  ObjectLockEnabledForBucket: true
});
try {
  await client.send(createCommand);
  console.log('Bucket created with Object Lock enabled');
} catch (err) {
  console.error('Error creating bucket:', err.message);
}
// Step 2: Set default retention rule
const lockConfigCommand = new PutObjectLockConfigurationCommand({
  Bucket: 'my-locked-bucket',
  ObjectLockConfiguration: {
    ObjectLockEnabled: 'Enabled',
    Rule: {
      DefaultRetention: {
        Mode: 'GOVERNANCE',
        Days: 30
      }
    }
  }
});
try {
  await client.send(lockConfigCommand);
  console.log('Default Object Lock configuration set successfully');
} catch (err) {
  console.error('Error setting lock config:', err.message);
}

Impostazione della configurazione di Object Lock

Imposta o aggiorna la regola di conservazione predefinita applicata a ogni nuovo oggetto caricato in un bucket.

const { PutObjectLockConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectLockConfigurationCommand({
  Bucket: 'my-object-lock-bucket',
  ObjectLockConfiguration: {
    ObjectLockEnabled: 'Enabled',
    Rule: {
      DefaultRetention: {
        Mode: 'COMPLIANCE',
        Days: 2
      }
    }
  }
});
try {
  await client.send(command);
  console.log('Object lock configuration set successfully');
} catch (err) {
  console.error('Error:', err.message);
}

Ottenere la configurazione di Object Lock

const { GetObjectLockConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectLockConfigurationCommand({
  Bucket: 'my-object-lock-bucket'
});
try {
  const response = await client.send(command);
  console.log('Object lock configuration retrieved successfully');
  console.log('ObjectLockEnabled:', response.ObjectLockConfiguration?.ObjectLockEnabled);
  console.log('Rule:', JSON.stringify(response.ObjectLockConfiguration?.Rule, null, 2));
} catch (err) {
  console.error('Error:', err.message);
}

Verifica dell'esistenza di un bucket (HEAD)

const { HeadBucketCommand } = require('ibm-cos-sdk-v2');
const command = new HeadBucketCommand({
  Bucket: 'my-bucket'
});
try {
  await client.send(command);
  console.log('Bucket exists');
} catch (err) {
  if (err.name === 'NotFound') {
    console.log('Bucket does not exist');
  } else {
    console.error('Error checking bucket:', err);
  }
}

Caricamento in streaming da un file

const fs = require('fs');
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const fileStream = fs.createReadStream('large-file.bin');
const command = new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'large-file.bin',
  Body: fileStream
});
try {
  const response = await client.send(command);
  console.log('File uploaded successfully');
} catch (err) {
  console.error('Error uploading file:', err);
}

Download in streaming su un file

const fs = require('fs');
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectCommand({
  Bucket: 'my-bucket',
  Key: 'large-file.bin'
});
try {
  const response = await client.send(command);
  const fileStream = fs.createWriteStream('downloaded-file.bin');
  response.Body.pipe(fileStream);
  await new Promise((resolve, reject) => {
    fileStream.on('finish', resolve);
    fileStream.on('error', reject);
    response.Body.on('error', reject);
  });
  console.log('File downloaded successfully');
} catch (err) {
  console.error('Error downloading file:', err);
}

Elenco di tutti gli oggetti con impaginazione

L'SDK di v2 fornisce paginatori integrati per le operazioni che restituiscono risultati troncati.

Utilizzo di un paginatore (consigliato):

const { paginateListObjectsV2 } = require('ibm-cos-sdk-v2');
async function listAllObjects(bucket, prefix) {
  const allObjects = [];
  const paginator = paginateListObjectsV2(
    { client: client, pageSize: 1000 },
    { Bucket: bucket, Prefix: prefix }
  );
  try {
    for await (const page of paginator) {
      if (page.Contents) {
        allObjects.push(...page.Contents);
      }
    }
    console.log('Total objects:', allObjects.length);
    return allObjects;
  } catch (err) {
    console.error('Error listing objects:', err);
    throw err;
  }
}

Impaginazione manuale:

const { ListObjectsV2Command } = require('ibm-cos-sdk-v2');
async function listAllObjects(bucket, prefix) {
  const allObjects = [];
  let continuationToken = undefined;
  do {
    const command = new ListObjectsV2Command({
      Bucket: bucket,
      Prefix: prefix,
      ContinuationToken: continuationToken
    });
    const response = await client.send(command);
    if (response.Contents) {
      allObjects.push(...response.Contents);
    }
    continuationToken = response.NextContinuationToken;
  } while (continuationToken);
  console.log('Total objects:', allObjects.length);
  return allObjects;
}

Generazione di URL pre-firmati

Gli URL pre-firmati consentono un accesso temporaneo e non autenticato agli oggetti. Per prima cosa, installa il pacchetto presigner:

npm install @ibm-cos/s3-request-presigner

GET pre-firmato URL (download):

const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const { getSignedUrl } = require('@ibm-cos/s3-request-presigner');
const command = new GetObjectCommand({
  Bucket: 'my-bucket',
  Key: 'my-object.txt'
});
try {
  const url = await getSignedUrl(client, command, { expiresIn: 3600 });
  console.log('Presigned URL:', url);
} catch (err) {
  console.error('Error generating presigned URL:', err);
}

PUT pre-firmato URL (caricamento):

const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const { getSignedUrl } = require('@ibm-cos/s3-request-presigner');
const command = new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'upload-object.txt',
  ContentType: 'text/plain'
});
try {
  const url = await getSignedUrl(client, command, { expiresIn: 3600 });
  console.log('Presigned PUT URL:', url);
} catch (err) {
  console.error('Error generating presigned URL:', err);
}

Ottenere una configurazion CORS

const { GetBucketCorsCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketCorsCommand({
  Bucket: 'my-bucket'
});
try {
  const response = await client.send(command);
  console.log('CORS rules:', response.CORSRules);
} catch (err) {
  console.error('Error getting CORS configuration:', err);
}

Eliminazione della configurazione di “ CORS ”

const { DeleteBucketCorsCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketCorsCommand({
  Bucket: 'my-bucket'
});
try {
  await client.send(command);
  console.log('Bucket CORS configuration deleted successfully');
} catch (err) {
  console.error('Error deleting CORS:', err);
}

Eliminazione dei tag degli oggetti

const { DeleteObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteObjectTaggingCommand({
  Bucket: 'my-bucket',
  Key: 'my-object.txt'
});
try {
  await client.send(command);
  console.log('Object tagging deleted successfully');
} catch (err) {
  console.error('Error deleting object tags:', err);
}

Caricamento di un oggetto con metadati personalizzati

const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'my-object.txt',
  Body: 'content',
  Metadata: {
    'author': 'John Doe',
    'department': 'Engineering'
  }
});
try {
  await client.send(command);
  console.log('Object uploaded with metadata');
} catch (err) {
  console.error('Error uploading object:', err);
}

Impostazione dell'assegnazione dei tag ai bucket

const { PutBucketTaggingCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketTaggingCommand({
  Bucket: 'my-bucket',
  Tagging: {
    TagSet: [
      { Key: 'Environment', Value: 'Production' },
      { Key: 'Project', Value: 'WebApp' }
    ]
  }
});
try {
  await client.send(command);
  console.log('Bucket tags updated');
} catch (err) {
  console.error('Error updating bucket tags:', err);
}

Eliminazione di una configurazione del ciclo di vita di un bucket

const { DeleteBucketLifecycleCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketLifecycleCommand({
  Bucket: 'my-bucket'
});
try {
  await client.send(command);
  console.log('Lifecycle configuration deleted successfully');
} catch (err) {
  console.error('Error deleting lifecycle:', err);
}

Configurazione dell'ACL del bucket

const { PutBucketAclCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketAclCommand({
  Bucket: 'my-bucket',
  ACL: 'public-read'
});
try {
  await client.send(command);
  console.log('Bucket ACL updated');
} catch (err) {
  console.error('Error updating bucket ACL:', err);
}

Ottenere l'ACL del bucket

const { GetBucketAclCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketAclCommand({
  Bucket: 'my-bucket'
});
try {
  const response = await client.send(command);
  console.log('Bucket ACL retrieved successfully');
  console.log('Owner:', response.Owner);
  console.log('Grants:', response.Grants);
} catch (err) {
  console.error('Error getting bucket ACL:', err);
}

Impostazione delle ACL degli oggetti

const { PutObjectAclCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectAclCommand({
  Bucket: 'my-bucket',
  Key: 'my-object.txt',
  ACL: 'public-read'
});
try {
  await client.send(command);
  console.log('Object ACL updated');
} catch (err) {
  console.error('Error updating object ACL:', err);
}

Ottenere l'ACL di un oggetto

const { GetObjectAclCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectAclCommand({
  Bucket: 'my-bucket',
  Key: 'my-object.txt'
});
try {
  const response = await client.send(command);
  console.log('Object ACL retrieved successfully');
  console.log('Owner:', response.Owner);
  console.log('Grants:', response.Grants);
} catch (err) {
  console.error('Error getting object ACL:', err);
}

Ottenere lo stato del controllo delle versioni

const { GetBucketVersioningCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketVersioningCommand({ Bucket: 'my-bucket' });
try {
  const response = await client.send(command);
  console.log('Bucket versioning configuration retrieved successfully');
  console.log('Status:', response.Status);
  // MFADelete is always undefined for IBM COS.
  console.log('MFADelete:', response.MFADelete);
} catch (err) {
  console.error('Error:', err.message);
}

Ottenere la versione di un oggetto specifico

const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectCommand({
  Bucket: 'my-bucket',
  Key: 'my-file.txt',
  VersionId: '<VERSION_ID>'
});
try {
  const response = await client.send(command);
  console.log('Version ID:', response.VersionId);
  // Stream response.Body to a file or buffer as needed.
} catch (err) {
  console.error('Error:', err.message);
}

Caricamento di un oggetto in un bucket con controllo delle versioni

Quando la gestione delle versioni è abilitata, ogni chiamata a PutObjectCommand crea una nuova versione. La risposta include il nuovo VersionId.

const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectCommand({
  Bucket: 'my-versioned-bucket',
  Key: 'my-file.txt',
  Body: 'Hello, World!'
});
try {
  const response = await client.send(command);
  console.log('Object uploaded successfully');
  console.log('Version ID:', response.VersionId);
} catch (err) {
  console.error('Error:', err.message);
}

Eliminazione di una versione specifica di un oggetto

Rimuove in modo definitivo una versione specifica di un oggetto includendone l' VersionId. Se in un bucket con controllo delle versioni manca l'ID della versione, viene creato invece un indicatore di eliminazione.

const { DeleteObjectCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteObjectCommand({
  Bucket: 'my-versioned-bucket',
  Key: 'my-file.txt',
  VersionId: 'YOUR_VERSION_ID_HERE'
});
try {
  const response = await client.send(command);
  console.log('Object version deleted successfully');
  console.log('Deleted Version ID:', response.VersionId);
  console.log('Delete Marker:', response.DeleteMarker ? 'Yes' : 'No');
} catch (err) {
  console.error('Error:', err.message);
}

Impostazione della protezione del bucket (WORM)

IBM Cloud Object Storage supporta la protezione dei bucket in modalità Write-Once-Read-Many (WORM) per garantire la conformità e la conservazione dei dati.

Impostazione della protezione del secchio:

const { PutBucketProtectionConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketProtectionConfigurationCommand({
  Bucket: 'my-protected-bucket',
  ProtectionConfiguration: {
    Status: 'Retention',
    MinimumRetention: { Days: 1 },
    DefaultRetention: { Days: 30 },
    MaximumRetention: { Days: 365 },
  },
});
try {
  await client.send(command);
  console.log('Bucket protection configuration set successfully');
} catch (err) {
  console.error('Error configuring protection:', err.message);
}

Come proteggere il secchio:

const { GetBucketProtectionConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketProtectionConfigurationCommand({
  Bucket: 'my-protected-bucket'
});
try {
  const response = await client.send(command);
  console.log('Bucket protection configuration retrieved successfully');
  console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
  console.error('Error getting protection config:', err);
}

Creazione di un bucket crittografato con il protocollo Key Protect

IBM Key Protect fornisce la gestione delle chiavi di crittografia per la crittografia a livello di bucket:

const { CreateBucketCommand } = require('ibm-cos-sdk-v2');
const command = new CreateBucketCommand({
  Bucket: 'my-encrypted-bucket',
  CreateBucketConfiguration: {
    LocationConstraint: 'us-south-standard'
  },
  IBMSSEKPEncryptionAlgorithm: 'AES256',
  IBMSSEKPCustomerRootKeyCrn: 'crn:v1:bluemix:public:kms:us-south:...'
});
try {
  await client.send(command);
  console.log('Encrypted bucket created');
} catch (err) {
  console.error('Error creating encrypted bucket:', err);
}

Rinominare un oggetto

RenameObject è un'operazione atomica lato server specifica per COS ( IBM ). Non vengono trasferiti dati: cambiano solo le chiavi:

const { RenameObjectCommand } = require('ibm-cos-sdk-v2');
const command = new RenameObjectCommand({
  Bucket: 'my-bucket',
  Key: 'new-object-key',                    // destination key
  RenameSource: 'my-bucket/old-object-key'  // source: bucket/key
});
try {
  await client.send(command);
  console.log('Object renamed successfully');
} catch (err) {
  console.error('Error:', err.message);
}

Aggiornamento della crittografia degli oggetti

UpdateObjectEncryption aggiorna il riferimento alla chiave di crittografia su un oggetto esistente. Richiede che sul bucket sia configurato IBM Key Protect o HPCS:

const { UpdateObjectEncryptionCommand } = require('ibm-cos-sdk-v2');
const command = new UpdateObjectEncryptionCommand({
  Bucket: 'my-bucket',
  Key: 'my-object.txt'
});
try {
  await client.send(command);
  console.log('Object encryption updated successfully');
} catch (err) {
  console.error('Error:', err.message);
}

Gestione della replica dei bucket

Ottenere la configurazione della replica:

const { GetBucketReplicationCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketReplicationCommand({ Bucket: 'my-bucket' });
try {
  const response = await client.send(command);
  console.log('Bucket replication configuration retrieved successfully');
  console.log('Rules:', JSON.stringify(response.ReplicationConfiguration?.Rules, null, 2));
} catch (err) {
  console.error('Error:', err.message);
}

Eliminazione della configurazione di replica:

const { DeleteBucketReplicationCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketReplicationCommand({ Bucket: 'my-bucket' });
try {
  await client.send(command);
  console.log('Bucket replication configuration deleted successfully');
} catch (err) {
  console.error('Error:', err.message);
}

Elenco degli errori di replica:

const { ListBucketReplicationFailuresCommand } = require('ibm-cos-sdk-v2');
const command = new ListBucketReplicationFailuresCommand({ Bucket: 'my-bucket' });
try {
  const response = await client.send(command);
  console.log('Bucket replication failures listed successfully');
  console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
  console.error('Error:', err.message);
}

Ripetere i tentativi di replica falliti:

const { PutBucketReplicationReattemptCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketReplicationReattemptCommand({ Bucket: 'my-bucket' });
try {
  await client.send(command);
  console.log('Bucket replication reattempt triggered successfully');
} catch (err) {
  console.error('Error:', err.message);
}

Creazione di una sessione

CreateSession crea un token di sessione temporaneo per un bucket IBM Cloud Object Storage:

const { CreateSessionCommand } = require('ibm-cos-sdk-v2');
const command = new CreateSessionCommand({ Bucket: 'my-bucket' });
try {
  const response = await client.send(command);
  console.log('Session created successfully');
  console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
  console.error('Error:', err.message);
}

In attesa che una risorsa sia pronta

I waiter effettuano il polling di una risorsa fino a quando questa non raggiunge lo stato desiderato, eliminando la necessità di cicli di polling manuali.

In attesa che esista un bucket:

const { waitUntilBucketExists } = require('ibm-cos-sdk-v2');
try {
  await waitUntilBucketExists(
    {
      client: client,
      maxWaitTime: 120, // Maximum wait time in seconds
      minDelay: 2,      // Minimum delay between checks in seconds
      maxDelay: 10      // Maximum delay between checks in seconds
    },
    { Bucket: 'my-bucket' }
  );
  console.log('Bucket exists and is ready');
} catch (err) {
  console.error('Bucket did not become available:', err);
}

In attesa che un oggetto esista:

const { waitUntilObjectExists } = require('ibm-cos-sdk-v2');
try {
  await waitUntilObjectExists(
    {
      client: client,
      maxWaitTime: 60,
      minDelay: 1,
      maxDelay: 5
    },
    {
      Bucket: 'my-bucket',
      Key: 'my-object.txt'
    }
  );
  console.log('Object exists and is ready');
} catch (err) {
  console.error('Object did not become available:', err);
}

Passi successivi