Utilización de Java
El SDK de IBM Cloud® Object Storage para Java proporciona características para aprovechar al máximo IBM Cloud Object Storage.
El SDK de IBM Cloud Object Storage para Java es muy completo y ofrece varias características y prestaciones que van más allá del ámbito y del espacio de esta guía. Para obtener más información sobre clases y métodos, consulte la documentación de Java. Encontrará el código fuente en el repositorio GitHub.
Obtención del SDK
La forma más sencilla de utilizar el SDK Java de IBM Cloud Object Storage consiste en utilizar Maven para gestionar 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 pom.xml
de ejemplo para utilizar el SDK Java de IBM
Cloud Object Storage para conectar con 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>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.ibm.cos</groupId>
<artifactId>ibm-cos-java-sdk</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
</project>
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 obtener más detalles sobre la creación del cliente, consulte la documentación de Java.
Ejemplos de código
En el código, debe eliminar los corchetes angulados o cualquier otro exceso de caracteres que se proporcionan aquí como ilustración.
Empezaremos con una clase de ejemplo completa que se ejecutará con algunas funciones básicas y luego exploraremos las clases individualmente. Esta clase CosExample
obtiene una lista de los objetos de un grupo existente, crea un
grupo nuevo y luego obtiene una lista de todos los grupos de la instancia de servicio.
Obtención de la información necesaria
bucketName
ynewBucketName
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. Tenga en cuenta que los nombres se reservan entre 10 y 15 minutos tras su supresión.apiKey
es el valor que se encuentra en la credencial de servicio comoapikey
.serviceInstanceId
es el valor que se encuentra en la credencial de servicio comoresource_instance_id
.endpointUrl
es un punto final de servicio URL, incluido el protocolohttps://
. No es el valor deendpoints
que se encuentra en la credencial de servicio. Para obtener más información sobre puntos finales, consulte Puntos finales y ubicaciones de almacenamiento.storageClass
es un código de suministro válido que se corresponde con el valor deendpoint
. Luego se utiliza como la variableLocationConstraint
de la API S3.location
se debe establecer en la parte de ubicación destorageClass
. Paraus-south-standard
, seríaus-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.time.LocalDateTime;
import java.util.List;
import com.ibm.cloud.objectstorage.ClientConfiguration;
import com.ibm.cloud.objectstorage.auth.AWSCredentials;
import com.ibm.cloud.objectstorage.auth.AWSStaticCredentialsProvider;
import com.ibm.cloud.objectstorage.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.ibm.cloud.objectstorage.services.s3.AmazonS3;
import com.ibm.cloud.objectstorage.services.s3.AmazonS3ClientBuilder;
import com.ibm.cloud.objectstorage.services.s3.model.Bucket;
import com.ibm.cloud.objectstorage.services.s3.model.ListObjectsRequest;
import com.ibm.cloud.objectstorage.services.s3.model.ObjectListing;
import com.ibm.cloud.objectstorage.services.s3.model.S3ObjectSummary;
import com.ibm.cloud.objectstorage.oauth.BasicIBMOAuthCredentials;
public class CosExample
{
public static void main(String[] args)
{
String bucketName = "<BUCKET_NAME>"; // eg my-unique-bucket-name
String newBucketName = "<NEW_BUCKET_NAME>"; // eg my-other-unique-bucket-name
String apiKey = "<API_KEY>"; // eg "W00YiRnLW4k3fTjMB-oiB-2ySfTrFBIQQWanc--P3byk"
String serviceInstanceId = "<SERVICE_INSTANCE_ID"; // eg "crn:v1:bluemix:public:cloud-object-storage:global:a/3bf0d9003abfb5d29761c3e97696b71c:d6f04d83-6c4f-4a62-a165-696756d63903::"
String endpointUrl = "https://s3.us-south.cloud-object-storage.appdomain.cloud"; // this could be any service endpoint
String storageClass = "us-south-standard";
String location = "us"; // not an endpoint, but used in a custom function below to obtain the correct URL
System.out.println("Current time: " + LocalDateTime.now());
AmazonS3 cosClient = createClient(apiKey, serviceInstanceId, endpointUrl, location);
listObjects(cosClient, bucketName);
createBucket(cosClient, newBucketName, storageClass);
listBuckets(cosClient);
}
public static AmazonS3 createClient(String apiKey, String serviceInstanceId, String endpointUrl, String location)
{
AWSCredentials credentials = new BasicIBMOAuthCredentials(apiKey, serviceInstanceId);
ClientConfiguration clientConfig = new ClientConfiguration()
.withRequestTimeout(5000)
.withTcpKeepAlive(true);
return AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withEndpointConfiguration(new EndpointConfiguration(endpointUrl, location))
.withPathStyleAccessEnabled(true)
.withClientConfiguration(clientConfig)
.build();
}
public static void listObjects(AmazonS3 cosClient, String bucketName)
{
System.out.println("Listing objects in bucket " + bucketName);
ObjectListing objectListing = cosClient.listObjects(new ListObjectsRequest().withBucketName(bucketName));
for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
System.out.println(" - " + objectSummary.getKey() + " " + "(size = " + objectSummary.getSize() + ")");
}
System.out.println();
}
public static void createBucket(AmazonS3 cosClient, String bucketName, String storageClass)
{
cosClient.createBucket(bucketName, storageClass);
}
public static void listBuckets(AmazonS3 cosClient)
{
System.out.println("Listing buckets");
final List<Bucket> bucketList = cosClient.listBuckets();
for (final Bucket bucket : bucketList) {
System.out.println(bucket.getName());
}
System.out.println();
}
}
Inicialización de la configuración
private static String COS_ENDPOINT = "<endpoint>"; // eg "https://s3.us.cloud-object-storage.appdomain.cloud"
private static String COS_API_KEY_ID = "<api-key>"; // eg "0viPHOY7LbLNa9eLftrtHPpTjoGv6hbLD1QalRXikliJ"
private static String COS_AUTH_ENDPOINT = "https://iam.cloud.ibm.com/identity/token";
private static String COS_SERVICE_CRN = "<resource-instance-id>"; // "crn:v1:bluemix:public:cloud-object-storage:global:a/<CREDENTIAL_ID_AS_GENERATED>:<SERVICE_ID_AS_GENERATED>::"
private static String COS_BUCKET_LOCATION = "<location>"; // eg "us"
public static void main(String[] args)
{
SDKGlobalConfiguration.IAM_ENDPOINT = COS_AUTH_ENDPOINT;
try {
_cos = createClient(COS_API_KEY_ID, COS_SERVICE_CRN, COS_ENDPOINT, COS_BUCKET_LOCATION);
} catch (SdkClientException sdke) {
System.out.printf("SDK Error: %s\n", sdke.getMessage());
} catch (Exception e) {
System.out.printf("Error: %s\n", e.getMessage());
}
}
public static AmazonS3 createClient(String api_key, String service_instance_id, String endpoint_url, String location)
{
AWSCredentials credentials = new BasicIBMOAuthCredentials(api_key, service_instance_id);
ClientConfiguration clientConfig = new ClientConfiguration().withRequestTimeout(5000);
clientConfig.setUseTcpKeepAlive(true);
AmazonS3 cos = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials))
.withEndpointConfiguration(new EndpointConfiguration(endpoint_url, location)).withPathStyleAccessEnabled(true)
.withClientConfiguration(clientConfig).build();
return cos;
}
Valores de clave
<endpoint>
- punto final público para su nube Object Storage (disponible en el panel IBM Cloud ). Para obtener más información sobre puntos finales, consulte Puntos finales y ubicaciones de almacenamiento.<api-key>
- clave api generada al crear las credenciales de servicio (se requiere acceso de escritura para los ejemplos de creación y eliminación)<resource-instance-id>
- iD de recurso para su nube Object Storage (disponible a través de IBM Cloud CLI o IBM Cloud Dashboard )<location>
- ubicación por defecto para su nube Object Storage (debe coincidir con la región que se utiliza para<endpoint>
)
Referencias de SDK
Clases
Determinación del punto final
Los métodos siguientes se pueden utilizar para determinar el punto final de servicio en función de la ubicación del grupo, el tipo de punto final (público o privado) y la región específica (opcional). Para obtener más información sobre puntos finales, consulte Puntos finales y ubicaciones de almacenamiento.
/**
* Returns a service endpoint based on the
* storage class location (i.e. us-standard, us-south-standard),
* endpoint type (public or private)
*/
public static String getEndpoint(String location, String endPointType) {
return getEndpoint(location, "", endPointType);
}
/**
* Returns a service endpoint based on the
* storage class location (i.e. us-standard, us-south-standard),
* specific region if desired (i.e. sanjose, amsterdam) - only use if you want a specific regional endpoint,
* endpoint type (public or private)
*/
public static String getEndpoint(String location, String region, String endpointType) {
HashMap locationMap = new HashMap<String, String>();
locationMap.put("us", "s3-api.us-geo");
locationMap.put("us-dallas", "s3-api.dal-us-geo");
locationMap.put("us-sanjose", "s3-api.sjc-us-geo");
locationMap.put("us-washington", "s3-api.wdc-us-geo");
locationMap.put("us-south", "s3.us-south");
locationMap.put("us-east", "s3.us-east");
locationMap.put("eu", "s3.eu-geo");
locationMap.put("eu-amsterdam", "s3.ams-eu-geo");
locationMap.put("eu-frankfurt", "s3.fra-eu-geo");
locationMap.put("eu-milan", "s3.mil-eu-geo");
locationMap.put("eu-gb", "s3.eu-gb");
locationMap.put("eu-germany", "s3.eu-de");
locationMap.put("ap", "s3.ap-geo");
locationMap.put("ap-tokyo", "s3.tok-ap-geo");
locationMap.put("che01", "s3.che01");
locationMap.put("mel01", "s3.mel01");
locationMap.put("tor01", "s3.tor01");
String key = location.substring(0, location.lastIndexOf("-")) + (region != null && !region.isEmpty() ? "-" + region : "");
String endpoint = locationMap.getOrDefault(key, null).toString();
if (endpoint != null) {
if (endpointType.toLowerCase() == "private")
endpoint += ".objectstorage.service.networklayer.com";
else
endpoint += ".objectstorage.s3.us-south.cloud-object-storage.appdomain.cloud.net";
}
return endpoint;
}
Creación de un nuevo grupo
public static void createBucket(String bucketName) {
System.out.printf("Creating new bucket: %s\n", bucketName);
_cos.createBucket(bucketName);
System.out.printf("Bucket: %s created!\n", bucketName);
}
Creación de un grupo con una clase de almacenamiento diferente
Puede consultar la lista de códigos de suministro válidos para LocationConstraint
en la guía de Storage Classes.
cos.createBucket("sample", "us-vault"); // the name of the bucket, and the storage class (LocationConstraint)
Referencias de SDK
Creación de un nuevo archivo de texto
public static void createTextFile(String bucketName, String itemName, String fileText) {
System.out.printf("Creating new item: %s\n", itemName);
byte[] arr = fileText.getBytes(StandardCharsets.UTF_8);
InputStream newStream = new ByteArrayInputStream(arr);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(arr.length);
PutObjectRequest req = new PutObjectRequest(bucketName, itemName, newStream, metadata);
_cos.putObject(req);
System.out.printf("Item: %s created!\n", itemName);
}
Tenga en cuenta que cuando se añaden metadatos personalizados a un objeto, es necesario crear un objeto ObjectMetadata
mediante el SDK, no enviar manualmente una cabecera personalizada que contenga x-amz-meta-{key}
.
Esto último puede provocar problemas al autenticar con las credenciales de HMAC.
Carga de un objeto desde un archivo
En este ejemplo se supone que el grupo sample
ya existe.
cos.putObject(
"sample", // the name of the destination bucket
"myfile", // the object key
new File("/home/user/test.txt") // the file name and path of the object to be uploaded
);
Carga de un objeto mediante una secuencia
En este ejemplo se supone que el grupo sample
ya existe.
String obj = "An example"; // the object to be stored
ByteArrayOutputStream theBytes = new ByteArrayOutputStream(); // create a new output stream to store the object data
ObjectOutputStream serializer = new ObjectOutputStream(theBytes); // set the object data to be serialized
serializer.writeObject(obj); // serialize the object data
serializer.flush();
serializer.close();
InputStream stream = new ByteArrayInputStream(theBytes.toByteArray()); // convert the serialized data to a new input stream to store
ObjectMetadata metadata = new ObjectMetadata(); // define the metadata
metadata.setContentType("application/x-java-serialized-object"); // set the metadata
metadata.setContentLength(theBytes.size()); // set metadata for the length of the data stream
cos.putObject(
"sample", // the name of the bucket to which the object is being written
"serialized-object", // the name of the object being written
stream, // the name of the data stream writing the object
metadata // the metadata for the object being written
);
De forma alternativa, puede utilizar un CipherInputStream
para cifrar más fácilmente la corriente de datos sin necesidad de sobrecargar el objeto InputStream
existente.
public CipherInputStream encryptStream(InputStream inputStream) {
// Generate key
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey aesKey = kgen.generateKey();
// Encrypt cipher
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
CipherInputStream cis = new CipherInputStream(inputStream, cipher);
return cis;
}
Descarga de un objeto en un archivo
En este ejemplo se supone que el grupo sample
ya existe.
GetObjectRequest request = new // create a new request to get an object
GetObjectRequest( // request the new object by identifying
"sample", // the name of the bucket
"myFile" // the name of the object
);
s3Client.getObject( // write the contents of the object
request, // using the request that was just created
new File("retrieved.txt") // to write to a new file
);
Descarga de un objeto mediante una secuencia
En este ejemplo se supone que el grupo sample
ya existe.
S3Object returned = cos.getObject( // request the object by identifying
"sample", // the name of the bucket
"serialized-object" // the name of the serialized object
);
S3ObjectInputStream s3Input = returned.getObjectContent(); // set the object stream
Copia de objetos
// copy an object within the same Bucket
cos.copyObject( // copy the Object, passing…
"sample", // the name of the Bucket in which the Object to be copied is stored,
"myFile.txt", // the name of the Object being copied from the source Bucket,
"sample", // the name of the Bucket in which the Object to be copied is stored,
"myFile.txt.backup" // and the new name of the copy of the Object to be copied
);
// copy an object between two Buckets
cos.copyObject( // copy the Object, passing…
"sample", // the name of the Bucket from which the Object will be copied,
"myFile.txt", // the name of the Object being copied from the source Bucket,
"backup", // the name of the Bucket to which the Object will be copied,
"myFile.txt" // and the name of the copied Object in the destination Bucket
);
Referencias de SDK
Clases
*Métodos
putObject
Excepción
El método putObject
puede lanzar la siguiente excepción aunque la carga del nuevo objeto se haya realizado correctamente:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1597)
at ibmcos.CoSExample.createTextFile(CoSExample.java:174)
at ibmcos.CoSExample.main(CoSExample.java:65)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499)
... 3 more
Causa raíz: las API de JAXB se consideran API de Java EE y ya no están contenidas en la variable path de clase predeterminada en Java SE 9.
Solución: añada la entrada siguiente al archivo pom.xml en la carpeta del proyecto y vuelva a empaquetar el proyecto.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Obtención de una lista de grupos disponibles
public static void getBuckets() {
System.out.println("Retrieving list of buckets");
final List<Bucket> bucketList = _cos.listBuckets();
for (final Bucket bucket : bucketList) {
System.out.printf("Bucket Name: %s\n", bucket.getName());
}
}
Referencias de SDK
Clases
Métodos
Obtención de la lista de elementos de un grupo (v2)
El objeto AmazonS3 contiene un método actualizado para listar el contenido (listObjectsV2). Este método le permite limitar el número de registros que se devuelven y recuperar los registros por lotes. Esto puede resultar útil para paginar los resultados dentro de una aplicación y mejorar el rendimiento.
public static void getBucketContentsV2(String bucketName, int maxKeys) {
System.out.printf("Retrieving bucket contents (V2) from: %s\n", bucketName);
boolean moreResults = true;
String nextToken = "";
while (moreResults) {
ListObjectsV2Request request = new ListObjectsV2Request()
.withBucketName(bucketName)
.withMaxKeys(maxKeys)
.withContinuationToken(nextToken);
ListObjectsV2Result result = _cos.listObjectsV2(request);
for(S3ObjectSummary objectSummary : result.getObjectSummaries()) {
System.out.printf("Item: %s (%s bytes)\n", objectSummary.getKey(), objectSummary.getSize());
}
if (result.isTruncated()) {
nextToken = result.getNextContinuationToken();
System.out.println("...More results in next batch!\n");
}
else {
nextToken = "";
moreResults = false;
}
}
System.out.println("...No more results!");
}
Referencias de SDK
Clases
Métodos
Obtención del contenido de archivo de un elemento determinado
public static void getItem(String bucketName, String itemName) {
System.out.printf("Retrieving item from bucket: %s, key: %s\n", bucketName, itemName);
S3Object item = _cos.getObject(new GetObjectRequest(bucketName, itemName));
try {
final int bufferSize = 1024;
final char[] buffer = new char[bufferSize];
final StringBuilder out = new StringBuilder();
InputStreamReader in = new InputStreamReader(item.getObjectContent());
for (; ; ) {
int rsz = in.read(buffer, 0, buffer.length);
if (rsz < 0)
break;
out.append(buffer, 0, rsz);
}
System.out.println(out.toString());
} catch (IOException ioe){
System.out.printf("Error reading file %s: %s\n", name, ioe.getMessage());
}
}
Referencias de SDK
Clases
Métodos
Supresión de un elemento de un grupo
public static void deleteItem(String bucketName, String itemName) {
System.out.printf("Deleting item: %s\n", itemName);
_cos.deleteObject(bucketName, itemName);
System.out.printf("Item: %s deleted!\n", itemName);
}
Referencias de SDK
Métodos
Supresión de varios elementos de un grupo
La solicitud de supresión puede contener un máximo de 1000 claves que desea suprimir. Aunque esto es muy útil para reducir el impacto en el rendimiento por petición, tenga cuidado al eliminar un gran número de claves. Tenga también en cuenta los tamaños de los objetos para garantizar un rendimiento adecuado.
public static void deleteItems(String bucketName) {
DeleteObjectsRequest req = new DeleteObjectsRequest(bucketName);
req.withKeys(
"deletetest/testfile1.txt",
"deletetest/testfile2.txt",
"deletetest/testfile3.txt",
"deletetest/testfile4.txt",
"deletetest/testfile5.txt"
);
DeleteObjectsResult res = _cos.deleteObjects(req);
System.out.printf("Deleted items for %s\n", bucketName);
List<DeleteObjectsResult.DeletedObject> deletedItems = res.getDeletedObjects();
for(DeleteObjectsResult.DeletedObject deletedItem : deletedItems) {
System.out.printf("Deleted item: %s\n", deletedItem.getKey());
}
}
Referencias de SDK
Clases
Métodos
Supresión de un grupo
public static void deleteBucket(String bucketName) {
System.out.printf("Deleting bucket: %s\n", bucketName);
_cos.deleteBucket(bucketName);
System.out.printf("Bucket: %s deleted!\n", bucketName);
}
Referencias de SDK
Métodos
Comprobación de si un objeto se puede leer públicamente
public static void getItemACL(String bucketName, String itemName) {
System.out.printf("Retrieving ACL for %s from bucket: %s\n", itemName, bucketName);
AccessControlList acl = _cos.getObjectAcl(bucketName, itemName);
List<Grant> grants = acl.getGrantsAsList();
for (Grant grant : grants) {
System.out.printf("User: %s (%s)\n", grant.getGrantee().getIdentifier(), grant.getPermission().toString());
}
}
Referencias de SDK
Clases
Métodos
Ejecución de una carga de varias partes
public static void multiPartUpload(String bucketName, String itemName, String filePath) {
File file = new File(filePath);
if (!file.isFile()) {
System.out.printf("The file '%s' does not exist or is not accessible.\n", filePath);
return;
}
System.out.printf("Starting multi-part upload for %s to bucket: %s\n", itemName, bucketName);
InitiateMultipartUploadResult mpResult = _cos.initiateMultipartUpload(new InitiateMultipartUploadRequest(bucketName, itemName));
String uploadID = mpResult.getUploadId();
//begin uploading the parts
//min 5MB part size
long partSize = 1024 * 1024 * 5;
long fileSize = file.length();
long partCount = ((long)Math.ceil(fileSize / partSize)) + 1;
List<PartETag> dataPacks = new ArrayList<PartETag>();
try {
long position = 0;
for (int partNum = 1; position < fileSize; partNum++) {
partSize = Math.min(partSize, (fileSize - position));
System.out.printf("Uploading to %s (part %s of %s)\n", name, partNum, partCount);
UploadPartRequest upRequest = new UploadPartRequest()
.withBucketName(bucketName)
.withKey(itemName)
.withUploadId(uploadID)
.withPartNumber(partNum)
.withFileOffset(position)
.withFile(file)
.withPartSize(partSize);
UploadPartResult upResult = _cos.uploadPart(upRequest);
dataPacks.add(upResult.getPartETag());
position += partSize;
}
//complete upload
_cos.completeMultipartUpload(new CompleteMultipartUploadRequest(bucketName, itemName, uploadID, dataPacks));
System.out.printf("Upload for %s Complete!\n", itemName);
} catch (SdkClientException sdke) {
System.out.printf("Multi-part upload aborted for %s\n", itemName);
System.out.printf("Upload Error: %s\n", sdke.getMessage());
_cos.abortMultipartUpload(new AbortMultipartUploadRequest(bucketName, itemName, uploadID));
}
}
Referencias de SDK
Clases
- AbortMultipartUploadRequest
- CompleteMultipartUploadRequest
- InitiateMultipartUploadRequest
- InitiateMultipartUploadResult
- SdkClientException
- UploadPartRequest
- UploadPartResult
Métodos
Creación de una política de copias de seguridad
public static void main(String[] args) {
try {
// Initialize authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize ResourceConfiguration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// Generate unique backup vault name
String backupVaultName = "vault-" + UUID.randomUUID().toString();
// Create backup policy
CreateBackupPolicyOptions backupPolicyOptions = new CreateBackupPolicyOptions.Builder()
.bucket(SOURCE_BUCKET_NAME)
.initialRetention(new DeleteAfterDays.Builder().deleteAfterDays(1).build())
.policyName(BACKUP_POLICY_NAME)
.targetBackupVaultCrn(BACKUP_VAULT_CRN)
.backupType("continuous").build();
Response<BackupPolicy> createResult = rcClient.createBackupPolicy(backupPolicyOptions).execute();
System.out.println("Policy Name:");
System.out.println(createResult.getResult().getPolicyName());
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Listado de una política de copias de seguridad
public static void main(String[] args) {
try {
// Initialize IAM authenticator and Resource Configuration client
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// List all backup policies
ListBackupPoliciesOptions listOptions = new ListBackupPoliciesOptions.Builder()
.bucket(SOURCE_BUCKET_NAME)
.build();
Response<BackupPolicyCollection> listResponse = rcClient.listBackupPolicies(listOptions).execute();
System.out.println("\nList of backup policies:");
List<?> policies = listResponse.getResult().getBackupPolicies();
for (Object policy : policies) {
System.out.println(policy);
}
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Obtener una política de copias de seguridad
public static void main(String[] args) {
try {
// Setup IAM Authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// Generate unique policy name
String policyName = "policy_name_" + UUID.randomUUID().toString();
// Fetch backup policy using policy ID
GetBackupPolicyOptions getOptions = new GetBackupPolicyOptions.Builder()
.bucket(SOURCE_BUCKET_NAME)
.policyId(POLICY_ID)
.build();
Response<BackupPolicy> getResponse = rcClient.getBackupPolicy(getOptions).execute();
BackupPolicy fetchedPolicy = getResponse.getResult();
System.out.println("\nFetched Backup Policy Details:");
System.out.println(fetchedPolicy);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Eliminar una política de copia de seguridad
public static void main(String[] args) {
try {
// Setup IAM Authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// Delete the created backup policy
DeleteBackupPolicyOptions deleteOptions = new DeleteBackupPolicyOptions.Builder()
.bucket(SOURCE_BUCKET_NAME)
.policyId(POLICY_ID)
.build();
rcClient.deleteBackupPolicy(deleteOptions).execute();
System.out.printf("Backup policy '%s' deleted successfully.%n", POLICY_ID);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Creación de una copia de seguridad
public static void main(String[] args) {
try {
// Setup IAM Authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// Generate unique backup vault name
String backupVaultName = "backup-vault-" + UUID.randomUUID();
// Create backup vault
CreateBackupVaultOptions createOptions = new CreateBackupVaultOptions.Builder()
.serviceInstanceId(SERVICE_INSTANCE_ID)
.backupVaultName(BACKUP_VAULT_NAME)
.region(REGION)
.build();
Response<BackupVault> response = rcClient.createBackupVault(createOptions).execute();
BackupVault vault = response.getResult();
System.out.println("Backup vault created:");
System.out.println(vault);
} catch (Exception e) {
System.err.println("Error creating backup vault: " + e.getMessage());
e.printStackTrace();
}
}
Listado de bóvedas de seguridad
public static void main(String[] args) {
try {
// Setup IAM Authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// List backup vaults
ListBackupVaultsOptions listBackupVaultsOptions = new ListBackupVaultsOptions.Builder().
serviceInstanceId(SERVICE_INSTANCE_ID).build();
Response<BackupVaultCollection> backupVaults = rcClient.listBackupVaults(listBackupVaultsOptions).execute();
System.out.println("\nList of backup vaults:");
if ( backupVaults.getResult().getBackupVaults() != null) {
for (String vault : backupVaults.getResult().getBackupVaults()) {
System.out.println(vault);
}
} else {
System.out.println("No backup vaults found.");
}
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Obtener bóvedas de seguridad
public static void main(String[] args) {
try {
// Initialize IAM Authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Create Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// Generate unique backup vault name
String backupVaultName = "backup-vault-" + UUID.randomUUID();
// Get backup vault details
GetBackupVaultOptions getOptions = new GetBackupVaultOptions.Builder()
.backupVaultName(BACKUP_VAULT_NAME)
.build();
Response<BackupVault> getResponse = rcClient.getBackupVault(getOptions).execute();
BackupVault vaultDetails = getResponse.getResult();
System.out.println("Backup vault details:");
System.out.println(vaultDetails);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Actualizar bóvedas de seguridad
public static void main(String[] args) {
try {
// Setup IAM Authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// Update vault: disable activity tracking and metrics monitoring
BackupVaultPatch backupVaultPatch = new BackupVaultPatch.Builder()
.activityTracking(new BackupVaultActivityTracking.Builder().managementEvents(Boolean.FALSE).build())
.metricsMonitoring(new BackupVaultMetricsMonitoring.Builder().usageMetricsEnabled(Boolean.FALSE).build())
.build();
UpdateBackupVaultOptions updateBackupVaultOptions = new UpdateBackupVaultOptions.Builder()
.backupVaultName(backupVaultName)
.backupVaultPatch(backupVaultPatch.asPatch()).build();
Response<BackupVault> backupVaultResponse2 = rcClient.updateBackupVault(updateBackupVaultOptions).execute();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Eliminar una copia de seguridad
public static void main(String[] args) {
try {
// Set up the authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// Delete backup vault
DeleteBackupVaultOptions deleteOptions = new DeleteBackupVaultOptions.Builder()
.backupVaultName(BACKUP_VAULT_NAME)
.build();
Response<Void> deleteResponse = rcClient.deleteBackupVault(deleteOptions).execute();
System.out.println("Failed to delete backup vault '" + BACKUP_VAULT_NAME + "'.");
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Rangos de recuperación de listados
public static void main(String[] args) {
try {
// Setup authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// List recovery ranges
ListRecoveryRangesOptions recoveryRangesOptions = new ListRecoveryRangesOptions.Builder()
.backupVaultName(BACKUP_VAULT_NAME)
.build();
Response<RecoveryRangeCollection> recoveryRangesResponse = rcClient.listRecoveryRanges(recoveryRangesOptions).execute();
System.out.println("Recovery Ranges:");
System.out.println(recoveryRangesResponse.getResult());
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Obtenga Rango de Recuperación
public static void main(String[] args) {
try {
// Setup authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// Fetch details of the recovery range
GetSourceResourceRecoveryRangeOptions recoveryRangeOptions = new GetSourceResourceRecoveryRangeOptions.Builder()
.backupVaultName(BACKUP_VAULT_NAME)
.recoveryRangeId(RECOVERY_RANGE_ID)
.build();
Response<RecoveryRange> getRecoveryRangeResponse = rcClient.getSourceResourceRecoveryRange(recoveryRangeOptions).execute();
System.out.println("Recovery Range Details:");
System.out.println(getRecoveryRangeResponse.getResult());
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Actualizar el intervalo de recuperación
public static void main(String[] args) {
try {
// Setup authenticator
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
// Initialize Resource Configuration client
ResourceConfiguration rcClient = new ResourceConfiguration("resource-configuration", authenticator);
// Patch the recovery range (update retention to 99 days)
PatchSourceResourceRecoveryRangeOptions patchOptions = new PatchSourceResourceRecoveryRangeOptions.Builder()
.backupVaultName(BACKUP_VAULT_NAME)
.recoveryRangeId(RECOVERY_RANGE_ID)
.recoveryRangePatch(
new RecoveryRangePatch.Builder()
.retention(new DeleteAfterDays.Builder().deleteAfterDays(99).build())
.build()
)
.build();
Response<RecoveryRange> patchResponse = rcClient.patchSourceResourceRecoveryRange(patchOptions).execute();
System.out.println("Recovery Range successfully patched:");
System.out.println(patchResponse.getResult());
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Iniciar una restauración
public static void main(String[] args) {
try {
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
ResourceConfiguration RC_CLIENT = new ResourceConfiguration("resource-configuration", authenticator);
CreateRestoreOptions createRestoreOptions = new CreateRestoreOptions.Builder()
.backupVaultName(BACKUP_VAULT_NAME)
.recoveryRangeId(recoveryRangeId)
.restoreType("in_place")
.targetResourceCrn(TARGET_BUCKET_CRN)
.restorePointInTime(RESTORE_TIME)
.build();
Response<Restore> createRestoreCall = RC_CLIENT.createRestore(createRestoreOptions).execute();
String restoreId = createRestoreCall.getResult().getRestoreId();
GetRestoreOptions getRestoreOptions = new GetRestoreOptions.Builder().restoreId(restoreId).backupVaultName(backupVaultName).build();
Response<Restore> restoreResult = RC_CLIENT.getRestore(getRestoreOptions).execute();
System.out.println("Restore successfully:");
System.out.println(restoreResult);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Restaurar listado
public static void main(String[] args) {
try {
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
ResourceConfiguration RC_CLIENT = new ResourceConfiguration("resource-configuration", authenticator);
ListRestoresOptions listRestoreOptions = new ListRestoresOptions.Builder()
.backupVaultName(BACKUP_VAULT_NAME)
.build();
Response<RestoreList> listRestoreResponse = rcClient.listRestores(listRestoreOptions).execute();
System.out.println("Restore operations: " + listRestoreResponse.getResult());
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Obtener detalles de restauración
public static void main(String[] args) {
try {
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey(API_KEY)
.build();
ResourceConfiguration RC_CLIENT = new ResourceConfiguration("resource-configuration", authenticator);
Response<Restore> getRestoreOptions =
GetRestoreOptions.Builder()
.restoreId(restoreId)
.backupVaultName(BACKUP_VAULT_NAME)
.build();
Response<Restore> restoreResult = RC_CLIENT.getRestore(getRestoreOptions).execute();
System.out.println("Get Restore: " + restoreResult);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
Carga de objetos grandes mediante un gestor de transferencias
TransferManager
simplifica las transferencias de archivos de gran tamaño incorporando automáticamente las cargas de varias partes siempre que sea necesario estableciendo los parámetros de configuración.
public static void largeObjectUpload(String bucketName, String itemName, String filePath) throws IOException, InterruptedException {
File uploadFile = new File(filePath);
if (!uploadFile.isFile()) {
System.out.printf("The file '%s' does not exist or is not accessible.\n", filePath);
return;
}
System.out.println("Starting large file upload with TransferManager");
//set the part size to 5 MB
long partSize = 1024 * 1024 * 5;
//set the threshold size to 5 MB
long thresholdSize = 1024 * 1024 * 5;
String endPoint = getEndpoint(COS_BUCKET_LOCATION, "public");
AmazonS3 s3client = createClient(COS_API_KEY_ID, COS_SERVICE_CRN, endPoint, COS_BUCKET_LOCATION);
TransferManager transferManager = TransferManagerBuilder.standard()
.withS3Client(s3client)
.withMinimumUploadPartSize(partSize)
.withMultipartCopyThreshold(thresholdSize)
.build();
try {
Upload lrgUpload = transferManager.upload(bucketName, itemName, uploadFile);
lrgUpload.waitForCompletion();
System.out.println("Large file upload complete!");
}
catch (SdkClientException e) {
System.out.printf("Upload error: %s\n", e.getMessage());
}
finally {
transferManager.shutdownNow();
}
Referencias de SDK
Clases
Métodos
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.
Antes de empezar
Se necesitan los elementos siguientes para crear un grupo con Key Protect habilitado:
- Un servicio de Key Protect suministrado
- Una clave raíz disponible (ya sea generada o importada)
Recuperación del CRN de la clave raíz
- Recupere el ID de instancia del servicio Key Protect
- Utilice la API de Key Protect para recuperar todas las claves disponibles
- Puede utilizar mandatos
curl
o un cliente de API REST, como Postman, para acceder a la API de Key Protect.
- Puede utilizar mandatos
- Recupere el CRN de la clave raíz que utilizará para activar Key Protect en el grupo. El CRN se parecerá al siguiente:
crn:v1:bluemix:public:kms:us-south:a/3d624cd74a0dea86ed8efe3101341742:90b6a1db-0fe1-4fe9-b91e-962c327df531:key:0bg3e33e-a866-50f2-b715-5cba2bc93234
Creación de un grupo con Key Protect habilitado
private static String COS_KP_ALGORITHM = "<algorithm>";
private static String COS_KP_ROOTKEY_CRN = "<root-key-crn>";
public static void createBucketKP(String bucketName) {
System.out.printf("Creating new encrypted bucket: %s\n", bucketName);
EncryptionType encType = new EncryptionType();
encType.setKmsEncryptionAlgorithm(COS_KP_ALGORITHM);
encType.setIBMSSEKMSCustomerRootKeyCrn(COS_KP_ROOTKEY_CRN);
CreateBucketRequest req = new CreateBucketRequest(bucketName).withEncryptionType(encType);
_cos.createBucket(req);
System.out.printf("Bucket: %s created!", bucketName);
}
Valores de clave
<algorithm>
- El algoritmo de cifrado utilizado para los nuevos objetos añadidos al cubo (por defecto es AES256 ).<root-key-crn>
- CRN de la clave raíz obtenida del servicio Key Protect.
Referencias de SDK
Clases
Métodos
Nuevas cabeceras para Key Protect
Se han definido cabeceras adicionales dentro de la clase Headers
:
public static final String IBM_SSE_KP_ENCRYPTION_ALGORITHM = "ibm-sse-kp-encryption-algorithm";
public static final String IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN = "ibm-sse-kp-customer-root-key-crn";
La misma sección de la implementación para crear un grupo que ya añade cabeceras de instancia de servicio de IAM añadirá 2 nuevas cabeceras de cifrado:
//Add IBM Service Instance Id & Encryption to headers
if ((null != this.awsCredentialsProvider ) && (this.awsCredentialsProvider.getCredentials() instanceof IBMOAuthCredentials)) {
IBMOAuthCredentials oAuthCreds = (IBMOAuthCredentials)this.awsCredentialsProvider.getCredentials();
if (oAuthCreds.getServiceInstanceId() != null) {
request.addHeader(Headers.IBM_SERVICE_INSTANCE_ID, oAuthCreds.getServiceInstanceId());
request.addHeader(Headers.IBM_SSE_KP_ENCRYPTION_ALGORITHM, createBucketRequest.getEncryptionType().getKpEncryptionAlgorithm());
request.addHeader(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN, createBucketRequest.getEncryptionType().getIBMSSEKPCustomerRootKeyCrn());
}
}
Los objetos ObjectListing
y HeadBucketResult
se han actualizado para incluir variables booleanas IBMSSEKPEnabled
y de cadena IBMSSEKPCustomerRootKeyCrn
con métodos getter y setter. Estas
variables guardarán los valores de las nuevas cabeceras.
GET bucket
public ObjectListing listObjects(String bucketName)
public ObjectListing listObjects(String bucketName, String prefix)
public ObjectListing listObjects(ListObjectsRequest listObjectsRequest)
La clase ObjectListing
necesitará 2 métodos adicionales:
ObjectListing listing = s3client.listObjects(listObjectsRequest)
String KPEnabled = listing.getIBMSSEKPEnabled();
String crkId = listing.getIBMSSEKPCrkId();
Las cabeceras adicionales se han definido dentro de la clase Headers
:
Headers.java
public static final string IBM_SSE_KP_ENABLED = "ibm-sse-kp-enabled";
public static final String IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN = "ibm-sse-kp-customer-root-key-crn";
La cabecera S3XmlResponseHandler, responsable de ejecutar unmarshall de todas las respuestas xml. Se ha añadido una comprobación que indica que el resultado es una instancia de ObjectListing
y las cabeceras recuperadas se añadirán
al objeto ObjectListing
:
if (result instanceof ObjectListing) {
if (!StringUtils.isNullOrEmpty(responseHeaders.get(Headers.IBM_SSE_KP_ENABLED)){
((ObjectListing) result).setIBMSSEKPEnabled(Boolean.parseBoolean(responseHeaders.get(Headers.IBM_SSE_KP_ENABLED)));
}
if (!StringUtils.isNullOrEmpty(responseHeaders.get(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN))) {
((ObjectListing) result).setIBMSSEKPCrk(responseHeaders.get(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN));
}
}
HEAD bucket
Se han definido cabeceras adicionales dentro de la clase Headers:
Headers.java
public static final String IBM_SSE_KP_ENABLED = "ibm-sse-kp-enabled";
public static final String IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN = "ibm-sse-kp-customer-root-key-crn";
Estas variables se llenan en HeadBucketResponseHandler.
HeadBucketResultHandler
result.setIBMSSEKPEnabled(response.getHeaders().get(Headers.IBM_SSE_KP_ENABLED));
result.setIBMSSEKPCrk(response.getHeaders().get(Headers. IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN));
Head Bucket Example
HeadBucketResult result = s3client.headBucket(headBucketRequest)
boolean KPEnabled = result.getIBMSSEKPEnabled();
String crn = result.getIBMSSEKPCUSTOMERROOTKEYCRN();
Utilización de la transferencia de alta velocidad de Aspera
Si instala la biblioteca de transferencia de alta velocidad de Aspera, puede utilizar transferencias de archivos de alta velocidad dentro de la aplicación. La biblioteca de Aspera es de origen cerrado y, por lo tanto, una dependencia opcional para el SDK de COS (que utiliza una licencia de Apache).
Cada sesión de transferencia de alta velocidad de Aspera genera un proceso ascp
individual que se ejecuta en la máquina cliente para realizar la transferencia. Asegúrese de que su entorno permita ejecutar dicho proceso.
Necesitará instancias de las clases S3 Client e IAM Token Manager para inicializar AsperaTransferManager
. s3Client
se necesita para obtener información de conexión de FASP para el grupo de destino de COS. tokenManager
se necesita para permitir que el SDK de transferencia de alta velocidad de Aspera se autentique con el grupo de destino de COS.
Inicialización de AsperaTransferManager
Antes de inicializar AsperaTransferManager
, asegúrese de que tiene objetos s3Client
y tokenManager
en funcionamiento.
Se recomienda utilizar TokenManager tokenManager = new DefaultTokenManager(new DelegateTokenProvider(apiKey));
y evitar .withTokenManager(tokenManager)
al crear AsperaTransferManager
con AsperaTransferManagerBuilder
.
Utilizar una sola sesión de transferencia de alta velocidad de Aspera no supone una gran ventaja, a no ser que espere una reducción significativa del ruido y de la pérdida de paquetes en la red. Por lo tanto, tenemos que indicar a AsperaTransferManager
que utilice varias sesiones utilizando la clase AsperaConfig
. Esto dividirá la transferencia entre varias sesiones paralelas que enviarán fragmentos de datos cuyo tamaño está definido por el valor threshold.
La configuración típica para utilizar la multisesión sería la siguiente:
- Tasa objetivo de 2500 MBps
- Umbral de 100 MB (este es el valor recomendado para la mayoría de aplicaciones)
AsperaTransferManagerConfig transferConfig = new AsperaTransferManagerConfig()
.withMultiSession(true);
AsperaConfig asperaConfig = new AsperaConfig()
.withTargetRateMbps(2500L)
.withMultiSessionThresholdMb(100);
TokenManager tokenManager = new DefaultTokenManager(new DelegateTokenProvider(API_KEY));
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(API_KEY, s3Client)
.withAsperaTransferManagerConfig(transferConfig)
.withAsperaConfig(asperaConfig)
.build();
En el ejemplo anterior, el sdk abarcará sesiones suficientes para intentar alcanzar la tasa objetivo de 2500 MBps.
Como alternativa, se puede configurar de forma explícita la gestión de sesiones en el sdk. Esto resulta útil en los casos en los que se desea un control más preciso sobre la utilización de la red.
La configuración típica para utilizar la multisesión explícita sería la siguiente:
- 2 o 10 sesiones
- Umbral de 100 MB (este es el valor recomendado para la mayoría de aplicaciones)
AsperaConfig asperaConfig = new AsperaConfig()
.withMultiSession(2)
.withMultiSessionThresholdMb(100);
TokenManager tokenManager = new DefaultTokenManager(new DelegateTokenProvider(API_KEY));
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(API_KEY, s3Client)
.withAsperaConfig(asperaConfig)
.build();
Para obtener el mejor rendimiento en la mayoría de los escenarios, utilice siempre varias sesiones para minimizar el procesamiento asociado a la instanciación de una transferencia de alta velocidad Aspera. Si la capacidad de red es como mínimo de 1 Gbps, debe utilizar 10 sesiones. Las redes de ancho de banda inferior deben utilizar dos sesiones.
Valores de clave
API_KEY
: una clave de API para un ID de usuario o de servicio con roles de Escritor o Gestor
Debe proporcionar una clave de API de IAM para crear AsperaTransferManager
. Las credenciales HMAC NO están soportadas actualmente. Para obtener más información acerca de IAM, pulse aquí.
Carga de archivos
String filePath = "<absolute-path-to-source-data>";
String bucketName = "<bucket-name>";
String itemName = "<item-name>";
// Load file
File inputFile = new File(filePath);
// Create AsperaTransferManager for FASP upload
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(API_KEY, s3Client).build();
// Upload test file and report progress
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.upload(bucketName, itemName, inputFile);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
Valores de clave
<bucket-name>
- nombre del bucket en su instancia de servicio Object Storage que tiene Aspera habilitado.<absolute-path-to-source-data>
- directorio y nombre de archivo para subir a Object Storage.<item-name>
- nombre del nuevo objeto añadido al cubo.
Descarga de archivos
String bucketName = "<bucket-name>";
String outputPath = "<absolute-path-to-file>";
String itemName = "<item-name>";
// Create local file
File outputFile = new File(outputPath);
outputFile.createNewFile();
// Create AsperaTransferManager for FASP download
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(COS_API_KEY_ID, s3Client)
.withTokenManager(tokenManager)
.withAsperaConfig(asperaConfig)
.build();
// Download file
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.download(bucketName, itemName, outputPath);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
Valores de clave
<bucket-name>
- nombre del bucket en su instancia de servicio Object Storage que tiene Aspera habilitado.<absolute-path-to-file>
- directorio y nombre de archivo para guardar de Object Storage.<item-name>
- nombre del objeto en el cubo.
Carga de directorios
String bucketName = "<bucket-name>";
String directoryPath = "<absolute-path-to-directory-for-new-file>";
String directoryPrefix = "<virtual-directory-prefix>";
boolean includeSubDirectories = true;
// Load Directory
File inputDirectory = new File(directoryPath);
// Create AsperaTransferManager for FASP upload
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(COS_API_KEY_ID, s3Client)
.withTokenManager(tokenManager)
.withAsperaConfig(asperaConfig)
.build();
// Upload test directory
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.uploadDirectory(bucketName, directoryPrefix, inputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
Valores de clave
<bucket-name>
- nombre del bucket en su instancia de servicio Object Storage que tiene Aspera habilitado.<absolute-path-to-directory>
- directorio de los archivos que se van a cargar en Object Storage.<virtual-directory-prefix>
- nombre del prefijo de directorio que se añadirá a cada archivo al cargarlo. Utilice una serie nula o vacía para cargar los archivos en la raíz del grupo.
Descarga de directorios
String bucketName = "<bucket-name>";
String directoryPath = "<absolute-path-to-directory>";
String directoryPrefix = "<virtual-directory-prefix>";
boolean includeSubDirectories = true;
// Load Directory
File outputDirectory = new File(directoryPath);
// Create AsperaTransferManager for FASP download
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(COS_API_KEY_ID, s3Client)
.withTokenManager(tokenManager)
.withAsperaConfig(asperaConfig)
.build();
// Download test directory
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
Valores de clave
<bucket-name>
- nombre del bucket en su instancia de servicio Object Storage que tiene Aspera habilitado.<absolute-path-to-directory>
- para guardar los archivos descargados de Object Storage.<virtual-directory-prefix>
- nombre del prefijo del directorio de cada archivo a descargar. Utilice una serie nula o vacía para descargar todos los archivos del grupo.
Modificación de la configuración de sesión por transferencia
Puede modificar los valores de configuración multisesión por transferencia pasando una instancia de AsperaConfig
a los métodos de carga y descarga utilizados. Con AsperaConfig
puede especificar el número de sesiones
y el tamaño mínimo de transferencia de archivos por sesión.
String bucketName = "<bucket-name>";
String filePath = "<absolute-path-to-file>";
String itemName = "<item-name>";
// Load file
File inputFile = new File(filePath);
// Create AsperaTransferManager for FASP upload
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(API_KEY, s3Client)
.withTokenManager(TOKEN_MANAGER)
.withAsperaConfig(asperaConfig)
.build();
// Create AsperaConfig to set number of sessions
// and file threshold per session.
AsperaConfig asperaConfig = new AsperaConfig().
withMultiSession(10).
withMultiSessionThresholdMb(100);
// Upload test file and report progress
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.upload(bucketName, itemName, inputFile, asperaConfig, null);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
Supervisión del progreso de la transferencia
La forma más sencilla de supervisar el progreso de las transferencias de archivos o directorios consiste en utilizar la propiedad isDone()
, que devuelve true
cuando la transferencia se haya completado.
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
while (!asperaTransaction.isDone()) {
System.out.println("Directory download is in progress");
//pause for 3 seconds
Thread.sleep(1000 * 3);
}
También puede comprobar si una transferencia está en cola para su proceso llamando al método onQueue
en AsperaTransaction
. onQueue
devolverá un booleano con true
que indica que la transferencia
está en cola.
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
while (!asperaTransaction.isDone()) {
System.out.println("Directory download is in queueing: " + asperaTransaction.onQueue());
//pause for 3 seconds
Thread.sleep(1000 * 3);
}
Para comprobar si una transferencia está en curso, llame al método de progreso en AsperaTransaction
.
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
while (!asperaTransaction.isDone()) {
System.out.println("Directory download is in progress: " + asperaTransaction.progress());
//pause for 3 seconds
Thread.sleep(1000 * 3);
}
De forma predeterminada, cada transferencia tiene un TransferProgress
conectado. TransferProgress
mostrará el número total de bytes transferidos y el porcentaje transferido del total de bytes que hay que transferir.
Para acceder a TransferProgress
de una transferencia, utilice el método getProgress
en AsperaTransaction
.
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
while (!asperaTransaction.isDone()) {
TransferProgress transferProgress = asperaTransaction.getProgress();
//pause for 3 seconds
Thread.sleep(1000 * 3);
}
Para ver sobre el número de bytes transferidos, llame al método getBytesTransferred
en TransferProgress
. Para ver el porcentaje transferido del número total de bytes a transferir, llame al método getPercentTransferred
en TransferProgress
.
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
while (!asperaTransaction.isDone()) {
TransferProgress transferProgress = asperaTransaction.getProgress();
System.out.println("Bytes transferred: " + transferProgress.getBytesTransferred());
System.out.println("Percent transferred: " + transferProgress.getPercentTransferred());
//pause for 3 seconds
Thread.sleep(1000 * 3);
}
Pausa/Reanudación/Cancelación
El SDK proporciona la capacidad de gestionar el progreso de las transferencias de archivos/directorios mediante los métodos siguientes del objeto AsperaTransfer
:
pause()
resume()
cancel()
No hay efectos secundarios de llamar a ninguno de los métodos mostrados anteriormente. El SDK se encarga de realizar la limpieza correspondiente.
El ejemplo siguiente muestra un posible uso de estos métodos:
String bucketName = "<bucket-name>";
String directoryPath = "<absolute-path-to-directory>";
String directoryPrefix = "<virtual-directory-prefix>";
boolean includeSubDirectories = true;
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(COS_API_KEY_ID, _cos)
.withTokenManager(TOKEN_MANAGER)
.build();
File outputDirectory = new File(directoryName);
System.out.println("Starting directory download...");
//download the directory from cloud storage
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
int pauseCount = 0;
while (!asperaTransaction.isDone()) {
System.out.println("Directory download in progress...");
//pause the transfer
asperaTransfer.pause();
//resume the transfer
asperaTransfer.resume();
//cancel the transfer
asperaTransfer.cancel();
}
System.out.println("Directory download complete!");
Resolución de problemas de Aspera
Problema: los desarrolladores que utilizan el JDK de Oracle en Linux o Mac OS X pueden experimentar caídas inesperadas y silenciosas durante las transferencias
Causa: el código nativo necesita sus propios manejadores de señales, que pueden haber sobrescrito los manejadores de señales de JVM. Es posible que sea necesario utilizar el recurso de encadenamiento de señales de JVM.
IBM® Los usuarios de JDK o Microsoft® Windows no se ven afectados.
Solución: enlace y cargue la biblioteca de encadenamiento de señales de JVM.
-
En Linux, localice la biblioteca compartida
libjsig.so
y defina la siguiente variable de entorno:LD_PRELOAD=<PATH_TO_SHARED_LIB>/libjsig.so
-
En Mac OS X, localice la biblioteca compartida
libjsig.dylib
y defina las siguientes variables de entorno:DYLD_INSERT_LIBRARIES=<PATH_TO_SHARED_LIB>/libjsig.dylib
DYLD_FORCE_FLAT_NAMESPACE=0
Visite la documentación de Oracle® JDK para obtener más información sobre el encadenamiento de señales.
Problema: UnsatisfiedLinkError
en Linux
Causa: el sistema no puede cargar las bibliotecas dependientes. En los registros de la aplicación se pueden ver errores como los siguientes:
libfaspmanager2.so: libawt.so: cannot open shared object file: No such file or directory
Solución: defina la siguiente variable de entorno:
LD_LIBRARY_PATH=<JAVA_HOME>/jre/lib/amd64/server:<JAVA_HOME>/jre/lib/amd64
Actualización de metadatos
Hay dos formas de actualizar los metadatos de un objeto existente:
- Una solicitud
PUT
con los nuevos metadatos y el contenido del objeto original - Ejecución de una solicitud
COPY
con los nuevos metadatos que especifican el objeto original como origen de la copia
Utilización de PUT para actualizar metadatos
La solicitud PUT
sobrescribe el contenido existente del objeto, por lo que primero debe descargarse y volver a cargarse con los nuevos metadatos.
public static void updateMetadataPut(String bucketName, String itemName, String key, String value) throws IOException {
System.out.printf("Updating metadata for item: %s\n", itemName);
//retrieve the existing item to reload the contents
S3Object item = _cos.getObject(new GetObjectRequest(bucketName, itemName));
S3ObjectInputStream itemContents = item.getObjectContent();
//read the contents of the item in order to set the content length and create a copy
ByteArrayOutputStream output = new ByteArrayOutputStream();
int b;
while ((b = itemContents.read()) != -1) {
output.write(b);
}
int contentLength = output.size();
InputStream itemCopy = new ByteArrayInputStream(output.toByteArray());
//set the new metadata
HashMap<String, String> userMetadata = new HashMap<String, String>();
userMetadata.put(key, value);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(contentLength);
metadata.setUserMetadata(userMetadata);
PutObjectRequest req = new PutObjectRequest(bucketName, itemName, itemCopy, metadata);
_cos.putObject(req);
System.out.printf("Updated metadata for item %s from bucket %s\n", itemName, bucketName);
}
Utilización de COPY para actualizar metadatos
public static void updateMetadataCopy(String bucketName, String itemName, String key, String value) {
System.out.printf("Updating metadata for item: %s\n", itemName);
//set the new metadata
HashMap<String, String> userMetadata = new HashMap<String, String>();
userMetadata.put(key, value);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setUserMetadata(userMetadata);
//set the copy source to itself
CopyObjectRequest req = new CopyObjectRequest(bucketName, itemName, bucketName, itemName);
req.setNewObjectMetadata(metadata);
_cos.copyObject(req);
System.out.printf("Updated metadata for item %s from bucket %s\n", itemName, bucketName);
}
Utilización de Immutable Object Storage
Adición de una configuración de protección a un grupo existente
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 grupos protegidos que ya no están bajo retención (el periodo de retención ha caducado y el objeto no tiene retenciones legales) vuelven a estar bajo retención cuando se sobrescriben. 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) {
System.out.printf("Adding protection to bucket: %s\n", bucketName);
BucketProtectionConfiguration newConfig = new BucketProtectionConfiguration()
.withStatus(BucketProtectionStatus.Retention)
.withMinimumRetentionInDays(10)
.withDefaultRetentionInDays(100)
.withMaximumRetentionInDays(1000);
cos.setBucketProtection(bucketName, newConfig);
System.out.printf("Protection added to bucket %s\n", bucketName);
}
public static void addProtectionConfigurationToBucketWithRequest(String bucketName) {
System.out.printf("Adding protection to bucket: %s\n", bucketName);
BucketProtectionConfiguration newConfig = new BucketProtectionConfiguration()
.withStatus(BucketProtectionStatus.Retention)
.withMinimumRetentionInDays(10)
.withDefaultRetentionInDays(100)
.withMaximumRetentionInDays(1000);
SetBucketProtectionConfigurationRequest newRequest = new SetBucketProtectionConfigurationRequest()
.withBucketName(bucketName)
.withProtectionConfiguration(newConfig);
cos.setBucketProtectionConfiguration(newRequest);
System.out.printf("Protection added to bucket %s\n", bucketName);
}
Comprobación de la protección sobre un grupo
public static void getProtectionConfigurationOnBucket(String bucketName) {
System.out.printf("Retrieving protection configuration from bucket: %s\n", bucketName;
BucketProtectionConfiguration config = cos.getBucketProtection(bucketName);
String status = config.getStatus();
System.out.printf("Status: %s\n", status);
if (!status.toUpperCase().equals("DISABLED")) {
System.out.printf("Minimum Retention (Days): %s\n", config.getMinimumRetentionInDays());
System.out.printf("Default Retention (Days): %s\n", config.getDefaultRetentionInDays());
System.out.printf("Maximum Retention (Days): %s\n", config.getMaximumRetentionInDays());
}
}
Carga de un objeto protegido
Los objetos de grupos protegidos que ya no están bajo retención (el periodo de retención ha caducado y el objeto no tiene retenciones legales) vuelven a estar bajo retención cuando se sobrescriben. 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.
Valor | Tipo | Descripción |
---|---|---|
Retention-Period |
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 el error 400 . Si no se especifica ninguno de los dos, se utiliza el periodo DefaultRetention del grupo. Cero (0 ) es un valor válido, siempre y cuando el periodo mínimo de retención
del grupo también sea 0 . |
Retention-expiration-date |
Fecha (formato ISO 8601) | Fecha en la que se podrá suprimir o modificar el objeto. Solo puede especificar esta cabecera o la cabecera Retention-Period. Si se especifican ambas, se devuelve el 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 serie larga de caracteres Y. El objeto no se puede sobrescribir ni suprimir hasta que se eliminen todas las retenciones legales asociadas con el objeto. |
public static void putObjectAddLegalHold(String bucketName, String objectName, String fileText, String legalHoldId) {
System.out.printf("Add legal hold %s to %s in bucket %s with a putObject operation.\n", legalHoldId, objectName, bucketName);
InputStream newStream = new ByteArrayInputStream(fileText.getBytes(StandardCharsets.UTF_8));
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(fileText.length());
PutObjectRequest req = new PutObjectRequest(
bucketName,
objectName,
newStream,
metadata
);
req.setRetentionLegalHoldId(legalHoldId);
cos.putObject(req);
System.out.printf("Legal hold %s added to object %s in bucket %s\n", legalHoldId, objectName, bucketName);
}
public static void copyProtectedObject(String sourceBucketName, String sourceObjectName, String destinationBucketName, String newObjectName) {
System.out.printf("Copy protected object %s from bucket %s to %s/%s.\n", sourceObjectName, sourceBucketName, destinationBucketName, newObjectName);
CopyObjectRequest req = new CopyObjectRequest(
sourceBucketName,
sourceObjectName,
destinationBucketName,
newObjectName
);
req.setRetentionDirective(RetentionDirective.COPY);
cos.copyObject(req);
System.out.printf("Protected object copied from %s/%s to %s/%s\n", sourceObjectName, sourceBucketName, destinationBucketName, newObjectName);
}
Adición o eliminación de una retención legal de un objeto protegido
El objeto da soporte a 100 retenciones legales:
- Un identificador de retención legal es una serie de caracteres con una longitud máxima de 64 caracteres y una longitud mínima de 1 carácter. Los caracteres válidos son letras, números,
!
,_
,.
,*
,(
,)
,-
y'
. - Si la adición de la retención legal especificada supera las 100 retenciones legales en total del objeto, la nueva retención legal no se añade y se devuelve el error
400
. - Si un identificador es demasiado largo, no se añade al objeto y se devuelve el error
400
. - Si un identificador contiene caracteres no válidos, no se añade al objeto y se devuelve el error
400
. - Si un identificador ya se está utilizando sobre un objeto, la retención legal existente no se modifica y la respuesta indica que el identificador ya se está utilizando con el error
409
. - Si un objeto no tiene metadatos de periodo de retención, se devuelve el error
400
y no se permite añadir ni eliminar una retención legal.
Es necesario que haya una cabecera de periodo de retención; de lo contrario, se devuelve el error 400
.
El usuario que añade o elimina una retención legal debe tener el permiso de Manager
sobre el grupo.
public static void addLegalHoldToObject(String bucketName, String objectName, String legalHoldId) {
System.out.printf("Adding legal hold %s to object %s in bucket %s\n", legalHoldId, objectName, bucketName);
cos.addLegalHold(
bucketName,
objectName,
legalHoldId
);
System.out.printf("Legal hold %s added to object %s in bucket %s!\n", legalHoldId, objectName, bucketName);
}
public static void deleteLegalHoldFromObject(String bucketName, String objectName, String legalHoldId) {
System.out.printf("Deleting legal hold %s from object %s in bucket %s\n", legalHoldId, objectName, bucketName);
cos.deleteLegalHold(
bucketName,
objectName,
legalHoldId
);
System.out.printf("Legal hold %s deleted from object %s in bucket %s!\n", legalHoldId, objectName, bucketName);
}
Ampliación del periodo de retenció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 (
Additional-Retention-Period
o un método similar) - nuevo periodo de ampliación en segundos (
Extend-Retention-From-Current-Time
o un método similar) - nueva fecha de caducidad de retención del objeto (
New-Retention-Expiration-Date
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 cualquiera de los casos, el parámetro de retención de ampliación se comprueba con respecto al periodo de retención actual y el parámetro ampliado solo se acepta si el periodo de retención actualizado es mayor que el periodo de retención
actual.
Los objetos de grupos protegidos que ya no están bajo retención (el periodo de retención ha caducado y el objeto no tiene retenciones legales) vuelven a estar bajo retención cuando se sobrescriben. 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) {
System.out.printf("Extend the retention period on %s in bucket %s by %s seconds.\n", objectName, bucketName, additionalSeconds);
ExtendObjectRetentionRequest req = new ExtendObjectRetentionRequest(
bucketName,
objectName)
.withAdditionalRetentionPeriod(additionalSeconds);
cos.extendObjectRetention(req);
System.out.printf("New retention period on %s is %s\n", objectName, additionalSeconds);
}
Obtención de una lista de las retenciones legales sobre un objeto protegido
Esta operación devuelve:
- Fecha de creación del objeto
- Periodo de retención del objeto en segundos
- Fecha de caducidad de retención calculada en función del periodo y de la fecha de creación
- Lista de retenciones legales
- Identificador de retención legal
- Indicación de fecha y hora en que se ha aplicado la retención legal
Si no hay ninguna retención legal sobre el objeto, se devuelve un LegalHoldSet
vacío. Si no se ha especificado ningún periodo de retención sobre el objeto, se devuelve el error 404
.
public static void listLegalHoldsOnObject(String bucketName, String objectName) {
System.out.printf("List all legal holds on object %s in bucket %s\n", objectName, bucketName);
ListLegalHoldsResult result = cos.listLegalHolds(
bucketName,
objectName
);
System.out.printf("Legal holds on bucket %s: \n", bucketName);
List<LegalHold> holds = result.getLegalHolds();
for (LegalHold hold : holds) {
System.out.printf("Legal Hold: %s", hold);
}
}
Crear un sitio web estático alojado
Esta operación requiere que se añada una sentencia de importación:
import com.ibm.cloud.objectstorage.services.s3.model.model.BucketWebsiteConfiguration;
Esta operación proporciona lo siguiente en la configuración y requiere un cliente configurado correctamente:
- Configuración de grupo para sufijo (documento de índice)
- Configuración de grupo para clave (documento de error)
cosClient.setBucketWebsiteConfiguration("<bucket_name>", new BucketWebsiteConfiguration("index.html", "error.html"));
Próximos pasos
Para obtener más información, consulte el Javadoc. El código fuente del proyecto se puede encontrar en el repositorioGitHub.