Utilizando Java V2

El SDK de IBM Cloud® Object Storage para Java v2 proporciona funciones para sacar el máximo partido a IBM Cloud Object Storage.

El SDK de IBM Cloud Object Storage para Java v2 es muy completo, con muchas funciones y capacidades que exceden el alcance y el espacio de esta guía. Para obtener documentación detallada sobre clases y métodos, consulte la documentación de referencia de la API Java. Encontrará el código fuente en el repositorio GitHub.

Novedades en v2

El SDK IBM Cloud Object Storage para Java v2 es una versión modernizada que se basa en la arquitectura del SDK AWS v2, aportando importantes mejoras:

  • Generadores inmutables: Todos los objetos de solicitud y respuesta utilizan patrones constructores inmutables para mejorar la seguridad de los hilos
  • Estructura moderna de paquetes: Nuevo espacio de nombres com.ibm.cos.v2.* con una organización más limpia
  • Soporte asíncrono mejorado: Introducción de S3AsyncClient para operaciones no bloqueantes
  • Streaming mejorado: Mejores API de streaming con RequestBody y ResponseTransformer
  • Gestión automática de tokens IAM: SDK gestiona la actualización de tokens IAM de forma automática
  • Seguridad de tipos: Comprobación de tipos en tiempo de compilación mejorada con constructores
  • Pila moderna HTTP: Soporte para Apache HTTP Client y Netty para operaciones asíncronas

Para los desarrolladores que migran desde v1, consulte la Guía de migración.

Obtención del SDK

La forma más sencilla de utilizar el SDK de IBM Cloud Object Storage Java v2 es utilizar Maven para gestionar las dependencias. Si no estás familiarizado con Maven, puedes ponerte manos a la obra con la guía Maven en 5 minutos.

Maven utiliza un archivo llamado pom.xml para especificar las bibliotecas (y sus versiones) necesarias para un proyecto Java. A continuación se muestra un archivo de ejemplo pom.xml para utilizar el SDK IBM Cloud Object Storage Java v2 para conectarse a Object Storage.

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.cos</groupId>
    <artifactId>docs</artifactId>
    <packaging>jar</packaging>
    <version>2.0-SNAPSHOT</version>
    <name>docs</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>com.ibm.cos.v2</groupId>
            <artifactId>cos-java-sdk</artifactId>
            <version>1.0.1</version>
        </dependency>
    </dependencies>
</project>

Referencias SDK

Clases principales

Credenciales

Configuración

Modalidad continua

Excepciones

Creación de credenciales de cliente y de origen

En el ejemplo siguiente, se crea un cliente cos y se configura proporcionando información de credenciales (clave de API e ID de instancia de servicio). Estos valores también se pueden tomar automáticamente de un archivo de credenciales o de variables de entorno.

Después de generar una credencial de servicio, el documento JSON resultante se puede guardar en ~/.bluemix/cos_credentials. El SDK tomará automáticamente las credenciales de este archivo, a menos que se establezcan explícitamente otras credenciales durante la creación del cliente. Si el archivo cos_credentials contiene claves de HMAC, el cliente se autentica con una firma; de lo contrario, el cliente utiliza la clave de API proporcionada para autenticarse mediante una señal de portadora.

Si se migra desde AWS S3, también puede obtener los datos de credenciales de origen de ~/.aws/credentials en el formato:

[default]
aws_access_key_id = {API_KEY}
aws_secret_access_key = {SERVICE_INSTANCE_ID}

Si existen tanto ~/.bluemix/cos_credentials como ~/.aws/credentials, prevalece cos_credentials.

Para más detalles sobre la construcción de clientes, consulte la documentación de referencia de la API Java.

Ejemplos de código

Comencemos con una clase de ejemplo completa que recorre algunas funcionalidades básicas. Esta clase CosExample enumera los objetos de un cubo existente, crea un nuevo cubo y, a continuación, enumera todos los cubos de la instancia de servicio.

Obtención de la información necesaria

  • bucketName y newBucketName son series exclusivas y DNS seguras. Puesto que los nombres de grupo son exclusivos en todo el sistema, estos valores se tienen que modificar si este ejemplo se ejecuta varias veces. Los nombres se reservan durante 10 - 15 minutos después de la eliminación.
  • apiKey es el valor que se encuentra en la credencial de servicio como apikey.
  • serviceInstanceId es el valor que se encuentra en la credencial de servicio como resource_instance_id.
  • endpointUrl es un punto final de servicio URL, incluido el protocolo https://. No es el valor de endpoints que se encuentra en la credencial de servicio. Para obtener más información sobre puntos finales, consulte Puntos finales y ubicaciones de almacenamiento.
  • location debe establecerse en la parte de ubicación de storageClass. Para us-south-standard, sería us-south. Esta variable solo se utiliza para el cálculo de firmas de HMAC, pero es necesaria para cualquier cliente, incluido este ejemplo que utiliza una clave de API de IAM.
package com.cos;

import java.net.URI;
import java.util.List;

import com.ibm.cos.v2.auth.credentials.AwsCredentials;
import com.ibm.cos.v2.auth.credentials.StaticCredentialsProvider;
import com.ibm.cos.v2.auth.credentials.ibmOAuth.BasicIBMOAuthCredentials;
import com.ibm.cos.v2.regions.Region;
import com.ibm.cos.v2.services.s3.S3Client;
import com.ibm.cos.v2.services.s3.model.*;

public class CosExample {

    private static String COS_ENDPOINT = "<endpoint>";
    private static String COS_API_KEY_ID = "<api-key>";
    private static String COS_SERVICE_INSTANCE_ID = "<service-instance-id>";
    private static String COS_LOCATION = "<location>";

    public static void main(String[] args) {
        System.out.println("Current time: " + new java.util.Date());

        // Create IBM COS credentials using API key
        AwsCredentials credentials = new BasicIBMOAuthCredentials(COS_API_KEY_ID, COS_SERVICE_INSTANCE_ID);

        // Create the S3 client
        S3Client cosClient = S3Client.builder()
                .endpointOverride(URI.create(COS_ENDPOINT))
                .credentialsProvider(StaticCredentialsProvider.create(credentials))
                .region(Region.of(COS_LOCATION))
                .build();

        listObjects("my-bucket", cosClient);
        createBucket("my-new-bucket", cosClient);
        listBuckets(cosClient);

        cosClient.close();
    }

    public static void listObjects(String bucketName, S3Client cosClient) {
        System.out.println("Listing objects in bucket: " + bucketName);

        ListObjectsV2Request request = ListObjectsV2Request.builder()
                .bucket(bucketName)
                .build();

        ListObjectsV2Response response = cosClient.listObjectsV2(request);
        List<S3Object> objects = response.contents();

        for (S3Object object : objects) {
            System.out.println("Item: " + object.key() + " (" + object.size() + " bytes)");
        }
    }

    public static void createBucket(String bucketName, S3Client cosClient) {
        System.out.println("Creating bucket: " + bucketName);

        CreateBucketRequest request = CreateBucketRequest.builder()
                .bucket(bucketName)
                .build();

        cosClient.createBucket(request);
        System.out.println("Bucket created: " + bucketName);
    }

    public static void listBuckets(S3Client cosClient) {
        System.out.println("Listing buckets:");

        ListBucketsResponse response = cosClient.listBuckets();
        List<Bucket> buckets = response.buckets();

        for (Bucket bucket : buckets) {
            System.out.println("Bucket Name: " + bucket.name());
        }
    }
}

Referencias clave

Determinación del punto final

Para obtener más información sobre puntos finales, consulte Puntos finales y ubicaciones de almacenamiento.

Los puntos finales siguen este patrón: https://s3.{region}.cloud-object-storage.appdomain.cloud

Ejemplos:

  • US South: https://s3.us-south.cloud-object-storage.appdomain.cloud
  • US East: https://s3.us-east.cloud-object-storage.appdomain.cloud
  • UE Gran Bretaña: https://s3.eu-gb.cloud-object-storage.appdomain.cloud

Creación de un nuevo grupo

public static void createBucket(String bucketName, S3Client cosClient) {
    System.out.println("Creating new bucket: " + bucketName);

    CreateBucketRequest request = CreateBucketRequest.builder()
            .bucket(bucketName)
            .build();

    cosClient.createBucket(request);

    System.out.println("Bucket: " + bucketName + " created!");
}

Referencia de clave

Creación de un grupo con una clase de almacenamiento diferente

public static void createBucketWithStorageClass(String bucketName, String storageClass, String location, S3Client cosClient) {
    System.out.println("Creating bucket: " + bucketName + " with storage class: " + storageClass);

    CreateBucketRequest request = CreateBucketRequest.builder()
            .bucket(bucketName)
            .ibmServiceInstanceId(COS_SERVICE_INSTANCE_ID)
            .build();

    cosClient.createBucket(request);

    System.out.println("Bucket: " + bucketName + " created with " + storageClass + " class storage!");
}

Las opciones de clase de almacenamiento incluyen:

  • us-south-standard / us-east-standard / eu-gb-standard- Almacenamiento estándar
  • us-south-vault / us-east-vault / eu-gb-vault- Almacenamiento en cámaras acorazadas
  • us-south-cold / us-east-cold / eu-gb-cold- Almacenamiento en cámaras frigoríficas
  • us-south-flex / us-east-flex / eu-gb-flex- Almacenamiento flexible

Referencia de clave

Creación de un nuevo archivo de texto

public static void createTextFile(String bucketName, String itemName, String fileText, S3Client cosClient) {
    System.out.println("Creating new item: " + itemName);

    PutObjectRequest request = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(itemName)
            .build();

    cosClient.putObject(request, RequestBody.fromString(fileText));

    System.out.println("Item: " + itemName + " created!");
}

Referencias clave

Carga de un objeto desde un archivo

public static void putObject(String bucketName, String itemName, String filePath, S3Client cosClient) {
    System.out.println("Creating new item: " + itemName);

    PutObjectRequest request = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(itemName)
            .build();

    cosClient.putObject(request, RequestBody.fromFile(new File(filePath)));

    System.out.println("Item: " + itemName + " created!");
}

Referencias clave

Carga de un objeto mediante una secuencia

public static void putObjectStream(String bucketName, String itemName, InputStream inputStream, long contentLength, S3Client cosClient) {
    System.out.println("Creating new item: " + itemName + " from input stream");

    PutObjectRequest request = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(itemName)
            .contentLength(contentLength)
            .build();

    cosClient.putObject(request, RequestBody.fromInputStream(inputStream, contentLength));

    System.out.println("Item: " + itemName + " created!");
}

Referencias clave

Descarga de un objeto en un archivo

public static void getObject(String bucketName, String itemName, String filePath, S3Client cosClient) {
    System.out.println("Retrieving item: " + itemName);

    GetObjectRequest request = GetObjectRequest.builder()
            .bucket(bucketName)
            .key(itemName)
            .build();

    cosClient.getObject(request, ResponseTransformer.toFile(new File(filePath)));

    System.out.println("Item: " + itemName + " downloaded to: " + filePath);
}

Referencias clave

Descarga de un objeto mediante una secuencia

public static void getObjectStream(String bucketName, String itemName, S3Client cosClient) {
    System.out.println("Retrieving item: " + itemName + " as stream");

    GetObjectRequest request = GetObjectRequest.builder()
            .bucket(bucketName)
            .key(itemName)
            .build();

    ResponseInputStream<GetObjectResponse> response = cosClient.getObject(request);

    try (InputStream inputStream = response) {
        // Process the input stream
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            // Process bytes
            System.out.write(buffer, 0, bytesRead);
        }
    } catch (IOException e) {
        System.err.println("Error reading object: " + e.getMessage());
    }

    System.out.println("\nItem: " + itemName + " retrieved!");
}

Referencias clave

Copia de objetos

public static void copyObject(String sourceBucketName, String sourceKey, String destinationBucketName, String destinationKey, S3Client cosClient) {
    System.out.println("Copying item: " + sourceKey + " from bucket: " + sourceBucketName +
                       " to: " + destinationKey + " in bucket: " + destinationBucketName);

    CopyObjectRequest request = CopyObjectRequest.builder()
            .sourceBucket(sourceBucketName)
            .sourceKey(sourceKey)
            .destinationBucket(destinationBucketName)
            .destinationKey(destinationKey)
            .build();

    cosClient.copyObject(request);

    System.out.println("Item: " + sourceKey + " copied!");
}

Referencias clave

Obtención de una lista de grupos disponibles

public static void listBuckets(S3Client cosClient) {
    System.out.println("Listing buckets:");

    ListBucketsResponse response = cosClient.listBuckets();
    List<Bucket> buckets = response.buckets();

    for (Bucket bucket : buckets) {
        System.out.println("Bucket Name: " + bucket.name());
    }
}

Referencias clave

Obtención del contenido de archivo de un elemento determinado

public static void getItem(String bucketName, String itemName, S3Client cosClient) {
    System.out.println("Retrieving item: " + itemName);

    GetObjectRequest request = GetObjectRequest.builder()
            .bucket(bucketName)
            .key(itemName)
            .build();

    ResponseInputStream<GetObjectResponse> response = cosClient.getObject(request);

    try {
        String content = new String(response.readAllBytes(), StandardCharsets.UTF_8);
        System.out.println("File Contents:\n" + content);
    } catch (IOException e) {
        System.err.println("Error reading object: " + e.getMessage());
    }
}

Referencias clave

Supresión de un elemento de un grupo

public static void deleteItem(String bucketName, String itemName, S3Client cosClient) {
    System.out.println("Deleting item: " + itemName);

    DeleteObjectRequest request = DeleteObjectRequest.builder()
            .bucket(bucketName)
            .key(itemName)
            .build();

    cosClient.deleteObject(request);

    System.out.println("Item: " + itemName + " deleted!");
}

Referencias clave

Supresión de varios elementos de un grupo

public static void deleteMultipleItems(String bucketName, List<String> itemNames, S3Client cosClient) {
    System.out.println("Deleting multiple items from bucket: " + bucketName);

    List<ObjectIdentifier> objectsToDelete = itemNames.stream()
            .map(key -> ObjectIdentifier.builder().key(key).build())
            .collect(Collectors.toList());

    Delete delete = Delete.builder()
            .objects(objectsToDelete)
            .build();

    DeleteObjectsRequest request = DeleteObjectsRequest.builder()
            .bucket(bucketName)
            .delete(delete)
            .build();

    DeleteObjectsResponse response = cosClient.deleteObjects(request);

    System.out.println("Deleted " + response.deleted().size() + " items!");
}

Referencias clave

Supresión de un grupo

El cubo debe estar vacío para poder ser eliminado.

public static void deleteBucket(String bucketName, S3Client cosClient) {
    System.out.println("Deleting bucket: " + bucketName);

    DeleteBucketRequest request = DeleteBucketRequest.builder()
            .bucket(bucketName)
            .build();

    cosClient.deleteBucket(request);

    System.out.println("Bucket: " + bucketName + " deleted!");
}

Referencias clave

Comprobación de si un objeto se puede leer públicamente

public static boolean isObjectPubliclyReadable(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Checking if object is publicly readable: " + objectKey);

    try {
        GetObjectAclRequest request = GetObjectAclRequest.builder()
                .bucket(bucketName)
                .key(objectKey)
                .build();

        GetObjectAclResponse response = cosClient.getObjectAcl(request);

        for (Grant grant : response.grants()) {
            if (grant.grantee().type() == Type.GROUP &&
                grant.grantee().uri() != null &&
                grant.grantee().uri().contains("AllUsers") &&
                grant.permission() == Permission.READ) {
                System.out.println("Object is publicly readable");
                return true;
            }
        }

        System.out.println("Object is not publicly readable");
        return false;
    } catch (S3Exception e) {
        System.err.println("Error checking object ACL: " + e.getMessage());
        return false;
    }
}

Referencias clave

Ejecución de una carga de varias partes

Cuando se trabaja con objetos grandes, se recomienda utilizar operaciones de carga de varias partes para escribir objetos en IBM Cloud Object Storage. Una carga de un solo objeto se puede realizar como un conjunto de partes, y dichas partes se pueden cargar de forma independiente en cualquier orden o en paralelo. Una vez finalizada la carga, IBM Cloud Object Storage presenta todas las partes como un solo objeto.

Las cargas de varias partes solo están disponibles para los objetos de más de 5 MB. Para los objetos de menos de 50 GB, se recomienda un tamaño de parte de entre 20 MB y 100 MB para obtener un rendimiento óptimo. En el caso de objetos más grandes, el tamaño de las partes se puede aumentar sin que ello afecte al rendimiento de forma significativa.

public static void multipartUpload(String bucketName, String itemName, String filePath, S3Client cosClient) {
    System.out.println("Starting multipart upload for: " + itemName);

    // Step 1: Initiate multipart upload
    CreateMultipartUploadRequest initiateRequest = CreateMultipartUploadRequest.builder()
            .bucket(bucketName)
            .key(itemName)
            .build();

    CreateMultipartUploadResponse initiateResponse = cosClient.createMultipartUpload(initiateRequest);
    String uploadId = initiateResponse.uploadId();
    System.out.println("Upload ID: " + uploadId);

    // Step 2: Upload parts
    int partNumber = 1;
    List<CompletedPart> completedParts = new ArrayList<>();
    ByteBuffer buffer = ByteBuffer.allocate(5 * 1024 * 1024); // 5 MB parts

    try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) {
        long fileSize = file.length();
        long position = 0;

        while (position < fileSize) {
            file.seek(position);
            long bytesRead = file.getChannel().read(buffer);

            buffer.flip();

            UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
                    .bucket(bucketName)
                    .key(itemName)
                    .uploadId(uploadId)
                    .partNumber(partNumber)
                    .build();

            UploadPartResponse partResponse = cosClient.uploadPart(
                    uploadPartRequest,
                    RequestBody.fromByteBuffer(buffer)
            );

            CompletedPart part = CompletedPart.builder()
                    .partNumber(partNumber)
                    .eTag(partResponse.eTag())
                    .build();
            completedParts.add(part);

            System.out.println("Uploaded part " + partNumber);

            buffer.clear();
            position += bytesRead;
            partNumber++;
        }
    } catch (IOException e) {
        System.err.println("Error during multipart upload: " + e.getMessage());

        // Abort the multipart upload on error
        AbortMultipartUploadRequest abortRequest = AbortMultipartUploadRequest.builder()
                .bucket(bucketName)
                .key(itemName)
                .uploadId(uploadId)
                .build();
        cosClient.abortMultipartUpload(abortRequest);
        return;
    }

    // Step 3: Complete multipart upload
    CompletedMultipartUpload completedUpload = CompletedMultipartUpload.builder()
            .parts(completedParts)
            .build();

    CompleteMultipartUploadRequest completeRequest = CompleteMultipartUploadRequest.builder()
            .bucket(bucketName)
            .key(itemName)
            .uploadId(uploadId)
            .multipartUpload(completedUpload)
            .build();

    cosClient.completeMultipartUpload(completeRequest);

    System.out.println("Multipart upload completed for: " + itemName);
}

Referencias clave

Utilización de Immutable Object Storage

Los usuarios pueden configurar buckets con una política inmutable Object Storage para evitar que los objetos se modifiquen o eliminen durante un periodo definido. El periodo de retención puede especificarse por objeto, o los objetos pueden heredar un periodo de retención por defecto establecido en el bucket.

Añadir una configuración de protección a un cubo

Esta implementación de la operación PUT utiliza el parámetro de consulta protection para definir los parámetros de retención para un grupo existente. Esta operación le permite establecer o cambiar el periodo de retención mínimo, predeterminado y máximo. Esta operación también le permite cambiar el estado de protección del grupo.

Los objetos que se escriben en un grupo protegido no se pueden suprimir hasta que transcurre el periodo de protección y se eliminan todas las retenciones legales sobre el objeto. Se proporciona el valor de retención predeterminado del grupo a un objeto a menos que se proporcione un valor específico de objeto cuando se crea el objeto. Los objetos de los buckets protegidos que ya no están bajo retención (el periodo de retención ha expirado y el objeto no tiene ninguna retención legal), cuando se sobrescriban, volverán a estar bajo retención. El nuevo periodo de retención se puede proporcionar como parte de la solicitud de sobrescritura del objeto o se asigna el tiempo de retención predeterminado del grupo al objeto.

Los valores mínimo y máximo admitidos para los ajustes del periodo de retención MinimumRetention, DefaultRetention, y MaximumRetention son un mínimo de 0 días y un máximo de 365243 días (1000 años).

public static void addProtectionConfigurationToBucket(String bucketName, S3Client cosClient) {
    System.out.println("Adding protection configuration to bucket: " + bucketName);

    BucketProtectionConfiguration protectionConfig = BucketProtectionConfiguration.builder()
            .status(BucketProtectionStatus.RETENTION)
            .minimumRetention(BucketProtectionMinimumRetention.builder()
                    .days(10)
                    .build())
            .defaultRetention(BucketProtectionDefaultRetention.builder()
                    .days(100)
                    .build())
            .maximumRetention(BucketProtectionMaximumRetention.builder()
                    .days(1000)
                    .build())
            .build();

    PutBucketProtectionConfigurationRequest request = PutBucketProtectionConfigurationRequest.builder()
            .bucket(bucketName)
            .protectionConfiguration(protectionConfig)
            .build();

    cosClient.putBucketProtectionConfiguration(request);

    System.out.println("Protection configuration added!");
}

Obtener la configuración de protección de un cubo

public static void getProtectionConfigurationOnBucket(String bucketName, S3Client cosClient) {
    System.out.println("Retrieving protection configuration for bucket: " + bucketName);

    GetBucketProtectionConfigurationRequest request = GetBucketProtectionConfigurationRequest.builder()
            .bucket(bucketName)
            .build();

    GetBucketProtectionConfigurationResponse response = cosClient.getBucketProtectionConfiguration(request);

    System.out.println("Status: " + response.status());
    System.out.println("Minimum Retention (days): " + response.minimumRetention().days());
    System.out.println("Default Retention (days): " + response.defaultRetention().days());
    System.out.println("Maximum Retention (days): " + response.maximumRetention().days());
}

Cargar un objeto protegido con retención

Los objetos de los buckets protegidos que ya no están bajo retención (el periodo de retención ha expirado y el objeto no tiene ninguna retención legal), cuando se sobrescriban, volverán a estar bajo retención. El nuevo periodo de retención se puede proporcionar como parte de la solicitud de sobrescritura del objeto o se asigna el tiempo de retención predeterminado del grupo al objeto.

Puede especificar parámetros de retención al cargar objetos en los buckets protegidos mediante cabeceras personalizadas:

Cabecera Tipo Descripción
Retention-Period Número entero no negativo (segundos) Periodo de retención para almacenar el objeto en segundos. El objeto no se puede sobrescribir ni suprimir hasta que transcurre el periodo de tiempo especificado en el período de retención. Si se especifica este campo y Retention-Expiration-Date se devuelve un error 400. Si no se especifica ninguna de los dos, se utiliza el periodo DefaultRetention del grupo. Cero (0) es un valor legal asumiendo que el periodo mínimo de retención del cubo también es 0.
Retention-Expiration-Date Fecha (formato ISO 8601) Fecha en la que es legal eliminar o modificar el objeto. Sólo puede especificar esto o el encabezado Retention-Period. Si se especifican ambos, se devolverá un error 400. Si no se especifica ninguna de los dos, se utiliza el periodo DefaultRetention del grupo.
Retention-Legal-Hold-Id string Una sola retención legal que se aplicará al objeto. Una retención legal es una cadena de caracteres de longitud Y. El objeto no se puede sobrescribir ni suprimir hasta que se eliminen todas las retenciones legales asociadas con el objeto.
public static void uploadProtectedObject(String bucketName, String objectKey, String filePath, S3Client cosClient) {
    System.out.println("Uploading protected object with retention: " + objectKey);

    // Option 1: Upload with retention period (in seconds)
    PutObjectRequest requestWithPeriod = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .retentionPeriod(2592000L)  // 30 days in seconds
            .build();

    cosClient.putObject(requestWithPeriod, RequestBody.fromFile(new File(filePath)));
    System.out.println("Object uploaded with 30-day retention period");
}

public static void uploadProtectedObjectWithExpirationDate(String bucketName, String objectKey, String filePath, S3Client cosClient) {
    System.out.println("Uploading protected object with expiration date: " + objectKey);

    // Option 2: Upload with retention expiration date
    Instant expirationDate = Instant.now().plus(90, ChronoUnit.DAYS);

    PutObjectRequest requestWithDate = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .retentionExpirationDate(expirationDate)
            .build();

    cosClient.putObject(requestWithDate, RequestBody.fromFile(new File(filePath)));
    System.out.println("Object uploaded with expiration date: " + expirationDate);
}

public static void uploadProtectedObjectWithLegalHold(String bucketName, String objectKey, String filePath, String legalHoldId, S3Client cosClient) {
    System.out.println("Uploading protected object with legal hold: " + objectKey);

    // Option 3: Upload with legal hold
    PutObjectRequest requestWithLegalHold = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .retentionLegalHoldId(legalHoldId)
            .build();

    cosClient.putObject(requestWithLegalHold, RequestBody.fromFile(new File(filePath)));
    System.out.println("Object uploaded with legal hold: " + legalHoldId);
}

public static void uploadProtectedObjectWithMultipleRetentionOptions(String bucketName, String objectKey, String filePath, String legalHoldId, S3Client cosClient) {
    System.out.println("Uploading protected object with retention period and legal hold: " + objectKey);

    // Option 4: Combine retention period with legal hold
    PutObjectRequest request = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .retentionPeriod(2592000L)  // 30 days
            .retentionLegalHoldId(legalHoldId)
            .build();

    cosClient.putObject(request, RequestBody.fromFile(new File(filePath)));
    System.out.println("Object uploaded with retention and legal hold");
}

Notas importantes:

  • No puede especificar Retention-Period y Retention-Expiration-Date en la misma solicitud.
  • Si no se especifica ningún parámetro de retención, se aplica el periodo de retención por defecto del bucket.
  • Las retenciones legales pueden combinarse con periodos de conservación.
  • Los objetos bajo retención o con retenciones legales no pueden borrarse ni sobrescribirse hasta que expire la retención y se eliminen todas las retenciones legales.

Referencias clave

Ampliación del plazo de conservación de un objeto protegido

El periodo de retención de un objeto solo se puede ampliar. No se puede reducir con respecto al valor configurado actualmente.

El valor de ampliación de retención se establece de una de las tres maneras siguientes:

  • Tiempo adicional a partir del valor actual (additionalRetentionPeriod o método similar)
  • Nuevo periodo de prórroga en segundos (extendRetentionFromCurrentTime o método similar)
  • Nueva fecha de caducidad de conservación del objeto (newRetentionExpirationDate o método similar)

El periodo de retención actual almacenado en los metadatos de objeto se incrementa en el tiempo adicional especificado o bien se sustituye por el nuevo valor, en función del parámetro establecido en la solicitud extendRetention. En todos los casos, el parámetro de retención ampliado se coteja con el periodo de retención actual y el parámetro ampliado sólo se acepta si el periodo de retención actualizado es mayor que el periodo de retención actual.

Los objetos de los buckets protegidos que ya no están bajo retención (el periodo de retención ha expirado y el objeto no tiene ninguna retención legal), cuando se sobrescriban, volverán a estar bajo retención. El nuevo periodo de retención se puede proporcionar como parte de la solicitud de sobrescritura del objeto o se asigna el tiempo de retención predeterminado del grupo al objeto.

public static void extendRetentionPeriodOnObject(String bucketName, String objectName, Long additionalSeconds, S3Client cosClient) {
    System.out.printf("Extending the retention period on %s in bucket %s by %s seconds.%n", objectName, bucketName, additionalSeconds);

    ExtendObjectRetentionRequest request = ExtendObjectRetentionRequest.builder()
            .bucket(bucketName)
            .key(objectName)
            .additionalRetentionPeriod(additionalSeconds)
            .build();

    cosClient.extendObjectRetention(request);

    System.out.printf("Retention period extended on %s by %s seconds%n", objectName, additionalSeconds);
}

Referencias clave

Utilización de Key Protect

Key Protect se puede añadir a un grupo de almacenamiento para cifrar los datos confidenciales en reposo en la nube.

Creación de un cubo con Key Protect

public static void createBucketWithKeyProtect(String bucketName, String kpRootKeyCrn, S3Client cosClient) {
    System.out.println("Creating bucket with Key Protect: " + bucketName);

    CreateBucketRequest request = CreateBucketRequest.builder()
            .bucket(bucketName)
            .ibmSSEKPEncryptionAlgorithm("AES256")
            .ibmSSEKPCustomerRootKeyCrn(kpRootKeyCrn)
            .build();

    cosClient.createBucket(request);

    System.out.println("Bucket created with Key Protect encryption!");
}

Carga de un objeto en un bucket habilitado para Key Protect

public static void putObjectToKPBucket(String bucketName, String objectKey, String filePath, S3Client cosClient) {
    System.out.println("Uploading object to Key Protect enabled bucket");

    PutObjectRequest request = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .build();

    cosClient.putObject(request, RequestBody.fromFile(new File(filePath)));

    System.out.println("Object uploaded with Key Protect encryption!");
}

Carga de objetos grandes mediante un gestor de transferencias

El Gestor de Transferencias proporciona una API sencilla para cargar y descargar objetos desde y hacia IBM Cloud Object Storage.

import com.ibm.cos.v2.transfer.s3.S3TransferManager;
import com.ibm.cos.v2.transfer.s3.model.*;

public static void uploadWithTransferManager(String bucketName, String objectKey, String filePath, S3Client cosClient) {
    System.out.println("Uploading with Transfer Manager: " + objectKey);

    // Create Transfer Manager
    S3TransferManager transferManager = S3TransferManager.builder()
            .s3Client(cosClient)
            .build();

    try {
        // Upload file
        UploadFileRequest uploadRequest = UploadFileRequest.builder()
                .putObjectRequest(req -> req.bucket(bucketName).key(objectKey))
                .source(Paths.get(filePath))
                .build();

        FileUpload upload = transferManager.uploadFile(uploadRequest);

        // Wait for upload to complete
        CompletedFileUpload completedUpload = upload.completionFuture().join();

        System.out.println("Upload completed: " + completedUpload.response().eTag());
    } finally {
        transferManager.close();
    }
}

Referencias clave

Actualización de metadatos

Actualizar los metadatos de un objeto existente

public static void updateObjectMetadata(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Updating metadata for object: " + objectKey);

    // Create new metadata
    Map<String, String> newMetadata = new HashMap<>();
    newMetadata.put("updated-by", "admin");
    newMetadata.put("update-date", LocalDate.now().toString());

    // Copy object to itself with new metadata
    CopyObjectRequest request = CopyObjectRequest.builder()
            .sourceBucket(bucketName)
            .sourceKey(objectKey)
            .destinationBucket(bucketName)
            .destinationKey(objectKey)
            .metadata(newMetadata)
            .metadataDirective(MetadataDirective.REPLACE)
            .build();

    cosClient.copyObject(request);

    System.out.println("Metadata updated!");
}

Referencias clave

Utilización de la transferencia de alta velocidad de Aspera

Aspera la integración de la transferencia de alta velocidad está disponible a través de IBM Aspera SDK. Consulte la documentación de Aspera para conocer los detalles de la integración con IBM Cloud Object Storage.

Para aplicaciones Java, puede utilizar Aspera Transfer SDK junto con el SDK IBM Cloud Object Storage v2 para transferencias de alta velocidad de archivos de gran tamaño.

Uso del bloqueo de objetos

Object Lock permite almacenar objetos utilizando un modelo de escritura única, lectura múltiple (WORM). El bloqueo de objetos puede ayudar a evitar que los objetos se borren o sobrescriban durante un tiempo determinado o indefinidamente.

Creación de un cubo con el bloqueo de objetos activado

El bloqueo de objetos debe activarse en el momento de la creación del cubo y no puede añadirse a un cubo existente.

public static void createBucketWithObjectLock(String bucketName, S3Client cosClient) {
    System.out.println("Creating bucket with Object Lock: " + bucketName);

    CreateBucketRequest request = CreateBucketRequest.builder()
            .bucket(bucketName)
            .objectLockEnabledForBucket(true)
            .build();

    cosClient.createBucket(request);

    System.out.println("Bucket created with Object Lock enabled!");
}

Establecer la retención de bloqueo de un objeto

Puede establecer la retención de un objeto para evitar que se elimine o sobrescriba. Hay dos modos de retención disponibles:

  • CUMPLIMIENTO: El objeto no puede ser sobrescrito ni borrado por ningún usuario, incluido el usuario root.
  • GOBERNANZA: Los usuarios con permisos especiales pueden modificar la configuración de retención o eliminar el objeto.
public static void putObjectRetention(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Setting object retention for: " + objectKey);

    // Create retention period of 90 days
    Instant retainUntil = Instant.now().plus(90, ChronoUnit.DAYS);

    // Create object lock retention with COMPLIANCE mode
    ObjectLockRetention retention = ObjectLockRetention.builder()
            .mode(ObjectLockRetentionMode.COMPLIANCE)
            .retainUntilDate(retainUntil)
            .build();

    // Apply retention to object
    PutObjectRetentionRequest request = PutObjectRetentionRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .retention(retention)
            .build();

    cosClient.putObjectRetention(request);

    System.out.println("Object retention set until: " + retainUntil);
}

Obtener información sobre la retención de Object Lock

public static void getObjectRetention(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Getting object retention for: " + objectKey);

    GetObjectRetentionRequest request = GetObjectRetentionRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .build();

    GetObjectRetentionResponse response = cosClient.getObjectRetention(request);

    System.out.println("Retention Mode: " + response.retention().mode());
    System.out.println("Retain Until: " + response.retention().retainUntilDate());
}

Fijar Bloqueo de objeto retención legal

Una retención legal ofrece la misma protección que un periodo de conservación, pero no tiene fecha de caducidad. Las retenciones legales siguen vigentes hasta que se retiran explícitamente.

public static void putObjectLegalHold(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Setting legal hold on: " + objectKey);

    ObjectLockLegalHold legalHold = ObjectLockLegalHold.builder()
            .status(ObjectLockLegalHoldStatus.ON)
            .build();

    PutObjectLegalHoldRequest request = PutObjectLegalHoldRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .legalHold(legalHold)
            .build();

    cosClient.putObjectLegalHold(request);

    System.out.println("Legal hold applied!");
}

Obtener el estado de retención legal de Object Lock

public static void getObjectLegalHold(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Getting legal hold status for: " + objectKey);

    GetObjectLegalHoldRequest request = GetObjectLegalHoldRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .build();

    GetObjectLegalHoldResponse response = cosClient.getObjectLegalHold(request);

    System.out.println("Legal Hold Status: " + response.legalHold().status());
}

Referencias clave

Uso de la configuración del ciclo de vida de los cubos

La configuración del ciclo de vida permite definir las acciones que IBM Cloud Object Storage aplica a un grupo de objetos. Puede utilizar políticas de ciclo de vida para cambiar objetos a diferentes clases de almacenamiento o hacer que caduquen tras un periodo de tiempo determinado.

Establecer una configuración de ciclo de vida en un cubo

public static void putBucketLifecycle(String bucketName, S3Client cosClient) {
    System.out.println("Setting lifecycle configuration on bucket: " + bucketName);

    // Create a transition to move objects to GLACIER after 30 days
    Transition transition = Transition.builder()
            .days(30)
            .storageClass(StorageClass.GLACIER)
            .build();

    // Create lifecycle rule filter
    LifecycleRuleFilter ruleFilter = LifecycleRuleFilter.builder()
            .prefix("archive/")  // Apply to objects with this prefix
            .build();

    // Create lifecycle rule
    LifecycleRule rule = LifecycleRule.builder()
            .id("archive-old-objects")
            .filter(ruleFilter)
            .transitions(transition)
            .status(ExpirationStatus.ENABLED)
            .build();

    // Create lifecycle configuration
    BucketLifecycleConfiguration lifecycleConfig = BucketLifecycleConfiguration.builder()
            .rules(rule)
            .build();

    // Apply lifecycle configuration to bucket
    PutBucketLifecycleConfigurationRequest request = PutBucketLifecycleConfigurationRequest.builder()
            .bucket(bucketName)
            .lifecycleConfiguration(lifecycleConfig)
            .build();

    cosClient.putBucketLifecycleConfiguration(request);

    System.out.println("Lifecycle configuration applied!");
}

Obtener la configuración del ciclo de vida de un cubo

public static void getBucketLifecycle(String bucketName, S3Client cosClient) {
    System.out.println("Getting lifecycle configuration for bucket: " + bucketName);

    GetBucketLifecycleConfigurationRequest request = GetBucketLifecycleConfigurationRequest.builder()
            .bucket(bucketName)
            .build();

    GetBucketLifecycleConfigurationResponse response = cosClient.getBucketLifecycleConfiguration(request);

    System.out.println("Found " + response.rules().size() + " lifecycle rules:");

    for (LifecycleRule rule : response.rules()) {
        System.out.println("  Rule ID: " + rule.id());
        System.out.println("  Status: " + rule.status());
        if (rule.hasTransitions()) {
            for (Transition t : rule.transitions()) {
                System.out.println("  Transition after " + t.days() + " days to " + t.storageClass());
            }
        }
    }
}

Eliminación de la configuración del ciclo de vida de un cubo

public static void deleteBucketLifecycle(String bucketName, S3Client cosClient) {
    System.out.println("Deleting lifecycle configuration from bucket: " + bucketName);

    DeleteBucketLifecycleRequest request = DeleteBucketLifecycleRequest.builder()
            .bucket(bucketName)
            .build();

    cosClient.deleteBucketLifecycle(request);

    System.out.println("Lifecycle configuration deleted!");
}

Referencias clave

Uso del control de versiones de cubos

El control de versiones permite guardar varias versiones de un objeto en el mismo cubo. Esto puede ayudarle a recuperarse de las acciones no intencionadas de los usuarios y de los fallos de las aplicaciones.

Activación del control de versiones en un cubo

public static void enableBucketVersioning(String bucketName, S3Client cosClient) {
    System.out.println("Enabling versioning on bucket: " + bucketName);

    VersioningConfiguration versioningConfig = VersioningConfiguration.builder()
            .status(BucketVersioningStatus.ENABLED)
            .build();

    PutBucketVersioningRequest request = PutBucketVersioningRequest.builder()
            .bucket(bucketName)
            .versioningConfiguration(versioningConfig)
            .build();

    cosClient.putBucketVersioning(request);

    System.out.println("Versioning enabled!");
}

Obtener el estado de las versiones de los cubos

public static void getBucketVersioning(String bucketName, S3Client cosClient) {
    System.out.println("Getting versioning status for bucket: " + bucketName);

    GetBucketVersioningRequest request = GetBucketVersioningRequest.builder()
            .bucket(bucketName)
            .build();

    GetBucketVersioningResponse response = cosClient.getBucketVersioning(request);

    System.out.println("Versioning Status: " + response.status());
}

Listado de versiones de objetos

public static void listObjectVersions(String bucketName, S3Client cosClient) {
    System.out.println("Listing object versions in bucket: " + bucketName);

    ListObjectVersionsRequest request = ListObjectVersionsRequest.builder()
            .bucket(bucketName)
            .build();

    ListObjectVersionsResponse response = cosClient.listObjectVersions(request);

    System.out.println("Versions:");
    for (ObjectVersion version : response.versions()) {
        System.out.println("  Key: " + version.key());
        System.out.println("  Version ID: " + version.versionId());
        System.out.println("  Is Latest: " + version.isLatest());
        System.out.println("  Last Modified: " + version.lastModified());
        System.out.println();
    }
}

Borrar una versión específica de un objeto

public static void deleteObjectVersion(String bucketName, String objectKey, String versionId, S3Client cosClient) {
    System.out.println("Deleting version " + versionId + " of object: " + objectKey);

    DeleteObjectRequest request = DeleteObjectRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .versionId(versionId)
            .build();

    cosClient.deleteObject(request);

    System.out.println("Object version deleted!");
}

Referencias clave


Uso de la lista de cubos ampliada

IBM Cloud Object Storage proporciona una API de listado ampliada que devuelve metadatos adicionales sobre los cubos, incluida información sobre la ubicación y la clase de almacenamiento.

public static void listBucketsExtended(S3Client cosClient) {
    System.out.println("Listing buckets with extended information:");

    ListBucketsExtendedRequest request = ListBucketsExtendedRequest.builder().build();

    ListBucketsExtendedResponse response = cosClient.listBucketsExtended(request);

    for (Bucket bucket : response.buckets()) {
        System.out.println("Bucket Name: " + bucket.name());
        System.out.println("  Creation Date: " + bucket.creationDate());

        // Extended metadata (IBM-specific)
        if (bucket.locationConstraint() != null) {
            System.out.println("  Location: " + bucket.locationConstraint());
        }
    }
}

Referencias clave

Uso del nivel de archivo y restauración de objetos

IBM Cloud Object Storage ofrece clases de almacenamiento de archivos (Glacier) para la conservación de datos a largo plazo a un coste menor. Los objetos archivados deben restaurarse antes de poder acceder a ellos.

Transición de objetos al almacenamiento de archivos

Puede utilizar políticas de ciclo de vida para transferir automáticamente objetos al almacenamiento de archivo después de un período de tiempo especificado.

public static void setArchiveRule(String bucketName, S3Client cosClient) {
    System.out.println("Setting archive rule on bucket: " + bucketName);

    // Create transition to Glacier after 30 days
    Transition transition = Transition.builder()
            .days(30)
            .storageClass(StorageClass.GLACIER)
            .build();

    // Create lifecycle rule
    LifecycleRuleFilter filter = LifecycleRuleFilter.builder()
            .prefix("archive/")
            .build();

    LifecycleRule rule = LifecycleRule.builder()
            .id("archive-rule")
            .filter(filter)
            .transitions(transition)
            .status(ExpirationStatus.ENABLED)
            .build();

    // Apply lifecycle configuration
    BucketLifecycleConfiguration config = BucketLifecycleConfiguration.builder()
            .rules(rule)
            .build();

    PutBucketLifecycleConfigurationRequest request = PutBucketLifecycleConfigurationRequest.builder()
            .bucket(bucketName)
            .lifecycleConfiguration(config)
            .build();

    cosClient.putBucketLifecycleConfiguration(request);

    System.out.println("Archive rule configured!");
}

Restaurar un objeto archivado

Los objetos archivados deben restaurarse antes de poder descargarse. Puede especificar el número de días que debe estar disponible la copia restaurada.

public static void restoreArchivedObject(String bucketName, String objectKey, int days, S3Client cosClient) {
    System.out.println("Restoring archived object: " + objectKey);

    // Create restore request with duration
    RestoreRequest restoreRequest = RestoreRequest.builder()
            .days(days)
            .glacierJobParameters(GlacierJobParameters.builder()
                    .tier(Tier.STANDARD)  // Options: STANDARD (12 hours), EXPEDITED (2 hours), BULK (5-12 hours)
                    .build())
            .build();

    RestoreObjectRequest request = RestoreObjectRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .restoreRequest(restoreRequest)
            .build();

    cosClient.restoreObject(request);

    System.out.println("Restore initiated. Object will be available for " + days + " days once restored.");
}

Comprobar el estado de la restauración

public static void checkRestoreStatus(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Checking restore status for: " + objectKey);

    HeadObjectRequest request = HeadObjectRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .build();

    HeadObjectResponse response = cosClient.headObject(request);

    if (response.restore() != null) {
        System.out.println("Restore Status: " + response.restore());

        // Parse restore status
        String restoreStatus = response.restore();
        if (restoreStatus.contains("ongoing-request=\"true\"")) {
            System.out.println("Restoration in progress...");
        } else if (restoreStatus.contains("ongoing-request=\"false\"")) {
            System.out.println("Object has been restored and is available for download");
        }
    } else {
        System.out.println("Object is not archived or no restore in progress");
    }
}

Recuperación acelerada de archivos

IBM Cloud Object Storage admite la recuperación acelerada de archivos para un acceso más rápido a los datos archivados:

  • Acelerado: 2 horas de recuperación
  • Estándar: tiempo de recuperación de 3 a 5 horas (por defecto)
  • A granel: 5-12 horas de recuperación (coste más bajo)
public static void restoreWithExpeditedRetrieval(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Restoring with expedited retrieval: " + objectKey);

    RestoreRequest restoreRequest = RestoreRequest.builder()
            .days(1)
            .glacierJobParameters(GlacierJobParameters.builder()
                    .tier(Tier.EXPEDITED)  // 2-hour retrieval
                    .build())
            .build();

    RestoreObjectRequest request = RestoreObjectRequest.builder()
            .bucket(bucketName)
            .key(objectKey)
            .restoreRequest(restoreRequest)
            .build();

    cosClient.restoreObject(request);

    System.out.println("Expedited restore initiated (2-hour retrieval)");
}

Referencias clave

Utilización de CORS (Cross-Origin Resource Sharing)

CORS permite a las aplicaciones web que se ejecutan en un dominio acceder a los recursos de IBM Cloud Object Storage desde otro dominio.

Configuración de CORS en un cubo

public static void setCorsConfiguration(String bucketName, S3Client cosClient) {
    System.out.println("Setting CORS configuration on bucket: " + bucketName);

    // Create CORS rule
    CORSRule corsRule = CORSRule.builder()
            .allowedMethods("GET", "PUT", "POST", "DELETE")
            .allowedOrigins("https://example.com")
            .allowedHeaders("*")
            .maxAgeSeconds(3000)
            .exposeHeaders("ETag", "x-amz-request-id")
            .build();

    // Create CORS configuration
    CORSConfiguration corsConfig = CORSConfiguration.builder()
            .corsRules(corsRule)
            .build();

    PutBucketCorsRequest request = PutBucketCorsRequest.builder()
            .bucket(bucketName)
            .corsConfiguration(corsConfig)
            .build();

    cosClient.putBucketCors(request);

    System.out.println("CORS configuration applied!");
}

Obtener la configuración de CORS

public static void getCorsConfiguration(String bucketName, S3Client cosClient) {
    System.out.println("Getting CORS configuration for bucket: " + bucketName);

    GetBucketCorsRequest request = GetBucketCorsRequest.builder()
            .bucket(bucketName)
            .build();

    GetBucketCorsResponse response = cosClient.getBucketCors(request);

    System.out.println("CORS Rules:");
    for (CORSRule rule : response.corsRules()) {
        System.out.println("  Allowed Methods: " + rule.allowedMethods());
        System.out.println("  Allowed Origins: " + rule.allowedOrigins());
        System.out.println("  Allowed Headers: " + rule.allowedHeaders());
        System.out.println("  Max Age: " + rule.maxAgeSeconds());
    }
}

Borrado de la configuración de CORS

public static void deleteCorsConfiguration(String bucketName, S3Client cosClient) {
    System.out.println("Deleting CORS configuration from bucket: " + bucketName);

    DeleteBucketCorsRequest request = DeleteBucketCorsRequest.builder()
            .bucket(bucketName)
            .build();

    cosClient.deleteBucketCors(request);

    System.out.println("CORS configuration deleted!");
}

Referencias clave


Uso de políticas de cubos

Las políticas de bucket proporcionan gestión de control de acceso para buckets y objetos. Están escritas en JSON y pueden conceder o denegar permisos a usuarios y servicios.

Establecer una política de cubos

public static void setBucketPolicy(String bucketName, S3Client cosClient) {
    System.out.println("Setting bucket policy on: " + bucketName);

    // Create policy document (JSON format)
    String policyText = "{"
            + "\"Version\": \"2012-10-17\","
            + "\"Statement\": [{"
            + "  \"Effect\": \"Allow\","
            + "  \"Principal\": {\"AWS\": \"*\"},"
            + "  \"Action\": \"s3:GetObject\","
            + "  \"Resource\": \"arn:aws:s3:::" + bucketName + "/*\""
            + "}]"
            + "}";

    PutBucketPolicyRequest request = PutBucketPolicyRequest.builder()
            .bucket(bucketName)
            .policy(policyText)
            .build();

    cosClient.putBucketPolicy(request);

    System.out.println("Bucket policy applied!");
}

Obtener una póliza de cubos

public static void getBucketPolicy(String bucketName, S3Client cosClient) {
    System.out.println("Getting bucket policy for: " + bucketName);

    GetBucketPolicyRequest request = GetBucketPolicyRequest.builder()
            .bucket(bucketName)
            .build();

    GetBucketPolicyResponse response = cosClient.getBucketPolicy(request);

    System.out.println("Policy: " + response.policy());
}

Eliminación de una política de cubos

public static void deleteBucketPolicy(String bucketName, S3Client cosClient) {
    System.out.println("Deleting bucket policy from: " + bucketName);

    DeleteBucketPolicyRequest request = DeleteBucketPolicyRequest.builder()
            .bucket(bucketName)
            .build();

    cosClient.deleteBucketPolicy(request);

    System.out.println("Bucket policy deleted!");
}

Referencias clave


Crear un sitio web estático alojado

IBM Cloud Object Storage permite alojar sitios web estáticos directamente desde los buckets. Puede configurar un bucket para servir contenido estático especificando un documento índice y un documento de error.

Esta operación requiere la siguiente sentencia import:

import com.ibm.cos.v2.services.s3.model.BucketWebsiteConfiguration;

Configuración del sitio web del cubo

Esta operación proporciona lo siguiente previa configuración y requiere un cliente correctamente configurado:

  • Configuración del cubo para el sufijo (documento índice)
  • Configuración del cubo para la clave (documento de error)
public static void setBucketWebsiteConfiguration(String bucketName, S3Client cosClient) {
    System.out.println("Setting website configuration for bucket: " + bucketName);

    // Create website configuration with index and error documents
    IndexDocument indexDocument = IndexDocument.builder()
            .suffix("index.html")
            .build();

    ErrorDocument errorDocument = ErrorDocument.builder()
            .key("error.html")
            .build();

    WebsiteConfiguration websiteConfig = WebsiteConfiguration.builder()
            .indexDocument(indexDocument)
            .errorDocument(errorDocument)
            .build();

    PutBucketWebsiteRequest request = PutBucketWebsiteRequest.builder()
            .bucket(bucketName)
            .websiteConfiguration(websiteConfig)
            .build();

    cosClient.putBucketWebsite(request);

    System.out.println("Website configuration set successfully!");
}

Obtención de la configuración del sitio web del cubo

public static void getBucketWebsiteConfiguration(String bucketName, S3Client cosClient) {
    System.out.println("Getting website configuration for bucket: " + bucketName);

    GetBucketWebsiteRequest request = GetBucketWebsiteRequest.builder()
            .bucket(bucketName)
            .build();

    GetBucketWebsiteResponse response = cosClient.getBucketWebsite(request);

    System.out.println("Index Document: " + response.indexDocument().suffix());
    System.out.println("Error Document: " + response.errorDocument().key());
}

Eliminación de la configuración del sitio web del cubo

public static void deleteBucketWebsiteConfiguration(String bucketName, S3Client cosClient) {
    System.out.println("Deleting website configuration from bucket: " + bucketName);

    DeleteBucketWebsiteRequest request = DeleteBucketWebsiteRequest.builder()
            .bucket(bucketName)
            .build();

    cosClient.deleteBucketWebsite(request);

    System.out.println("Website configuration deleted!");
}

Referencias clave

Tratamiento de errores y buenas prácticas

Manejo de excepciones del SDK

El SDK v2 utiliza tipos de excepción específicos para diferentes escenarios de error.

import com.ibm.cos.v2.services.s3.model.S3Exception;
import com.ibm.cos.v2.services.s3.model.NoSuchBucketException;
import com.ibm.cos.v2.services.s3.model.NoSuchKeyException;

public static void handleExceptions(String bucketName, String objectKey, S3Client cosClient) {
    try {
        GetObjectRequest request = GetObjectRequest.builder()
                .bucket(bucketName)
                .key(objectKey)
                .build();

        cosClient.getObject(request, ResponseTransformer.toBytes());

    } catch (NoSuchBucketException e) {
        System.err.println("Bucket does not exist: " + bucketName);
        System.err.println("Error Code: " + e.awsErrorDetails().errorCode());

    } catch (NoSuchKeyException e) {
        System.err.println("Object does not exist: " + objectKey);
        System.err.println("Error Code: " + e.awsErrorDetails().errorCode());

    } catch (S3Exception e) {
        System.err.println("S3 Error: " + e.awsErrorDetails().errorMessage());
        System.err.println("Error Code: " + e.awsErrorDetails().errorCode());
        System.err.println("Status Code: " + e.statusCode());

    } catch (Exception e) {
        System.err.println("Unexpected error: " + e.getMessage());
    }
}

Mejores prácticas para v2 SDK

  • Reutilice las instancias de S3Client: Crear clientes es caro. Reutilícelos en todas las solicitudes.
// Good: Create once, reuse
S3Client client = S3Client.builder()
        .endpointOverride(URI.create(endpoint))
        .credentialsProvider(StaticCredentialsProvider.create(credentials))
        .region(Region.of(region))
        .build();

// Use client for multiple operations
client.listBuckets();
client.putObject(...);
client.getObject(...);

// Close when done
client.close();
  • Utilizar la prueba con recursos: Asegura la limpieza adecuada de los recursos.
try (S3Client client = S3Client.builder()
        .endpointOverride(URI.create(endpoint))
        .credentialsProvider(StaticCredentialsProvider.create(credentials))
        .region(Region.of(region))
        .build()) {

    // Perform operations
    client.listBuckets();

} // Client automatically closed
  • Gestione archivos grandes con cargas multiparte: Para archivos de más de 5 MB, utiliza subidas multiparte.

  • Utilice Transfer Manager para transferencias de gran volumen: Proporciona carga automática multiparte, lógica de reintento y seguimiento del progreso.

  • Configure los tiempos de espera apropiados: Configura los tiempos de espera del cliente para tu caso de uso.

S3Client client = S3Client.builder()
        .endpointOverride(URI.create(endpoint))
        .credentialsProvider(StaticCredentialsProvider.create(credentials))
        .region(Region.of(region))
        .overrideConfiguration(ClientOverrideConfiguration.builder()
                .apiCallTimeout(Duration.ofMinutes(5))
                .apiCallAttemptTimeout(Duration.ofMinutes(2))
                .build())
        .build();

Referencias clave

Recursos adicionales

Obtención de ayuda

Esta documentación proporciona la estructura y las referencias del SDK para IBM Cloud Object Storage Java SDK v2. Para ver ejemplos de código de trabajo completos de todas las operaciones, consulte el directorio de ejemplos y la Guía de migración en el repositorio GitHub.