Utilisation de Java
Le SDK IBM Cloud® Object Storage pour Java offre des fonctions permettant de tirer le meilleur parti du service IBM Cloud Object Storage.
Le SDK IBM Cloud Object Storage pour Java est complet avec de nombreuses fonctions dépassant le cadre et l'objectif de ce guide. Pour obtenir une documentation détaillée sur les classes et les méthodes, voir la Javadoc. Le code source se trouve dans le référentiel GitHub.
Obtention du SDK
Le moyen le plus facile d'utiliser le SDK IBM Cloud Object Storage pour Java consiste à employer Maven pour gérer les dépendances. Si vous n'êtes pas familier avec Maven, vous pouvez vous lancer en utilisant le guide Maven en 5 minutes.
Maven utilise un fichier nommé pom.xml
pour spécifier les bibliothèques (et leurs versions) nécessaires pour un projet Java. Voici un exemple de fichier pom.xml
permettant d'utiliser le SDK IBM Cloud Object Storage
pour Java afin de se connecter à 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>
Création d'un client et sourçage de données d'identification
Dans l'exemple ci-après, un client cos
est créé et configuré en fournissant des données d'identification (clé d'API et ID d'instance de service). Ces valeurs peuvent aussi être automatiquement sourcées à partir d'un fichier de données
d'identification ou à partir de variables d'environnement.
Après avoir généré des données d'identification de service, le document JSON résultant peut être sauvegardé dans ~/.bluemix/cos_credentials
.
Le SDK source automatiquement les données d'identification de ce fichier, sauf si d'autres données d'identification sont explicitement définies lors de la création du client. Si le fichier cos_credentials
contient des clés HMAC,
le client s'authentifie à l'aide d'une signature, sinon, il utilise la clé d'API fournie pour s'authentifier à l'aide d'un jeton bearer.
Si vous effectuez une migration à partir de AWS S3, vous pouvez également sourcer des données d'identification à partir de ~/.aws/credentials
au format suivant :
[default]
aws_access_key_id = {API_KEY}
aws_secret_access_key = {SERVICE_INSTANCE_ID}
Si ~/.bluemix/cos_credentials
et ~/.aws/credentials
existent tous les deux, cos_credentials
est prioritaire.
Pour plus d'informations sur la construction client, voir la Javadoc.
Exemples de code
Dans votre code, vous devez supprimer les crochets ou tout autre caractère en excès qui sont fournis ici à titre d'illustration.
Commençons par un exemple de classe complet qui s'exécutera à travers certaines fonctionnalités de base. Ensuite nous explorerons les classes individuellement. Cette classe CosExample
répertoriera les objets contenus dans un compartiment
existant, créera un nouveau compartiment, puis répertoriera tous les compartiments contenus dans l'instance de service.
Collecte des informations requises
bucketName
etnewBucketName
sont des chaînes uniques et sécurisées DNS. Etant donné que les noms de compartiment sont uniques sur l'ensemble du système, ces valeurs devront être modifiées si cet exemple est exécuté plusieurs fois. Notez que les noms sont réservés pendant 10 à 15 minutes après leur suppression.apiKey
est la valeur trouvée dans le justificatif de service à l'adresseapikey
.serviceInstanceId
est la valeur trouvée dans le justificatif de service à l'adresseresource_instance_id
.endpointUrl
est un point d'aboutissement du service URL, y compris le protocolehttps://
. Il ne s'agit pas de la valeurendpoints
qui est trouvée dans les données d'identification de service. Pour plus d'informations sur les noeuds finaux, voir Noeuds finaux et emplacements de stockage.storageClass
est un code de mise à disposition valide qui correspond à la valeurendpoint
. Il est ensuite utilisé comme variableLocationConstraint
de l'API S3.location
doit avoir pour valeur la partie emplacement destorageClass
. Pourus-south-standard
, il s'agira deus-south
. Cette variable est utilisée uniquement pour le calcul des signatures HMAC, mais elle est requise pour tous les clients, dont cet exemple qui utilise une clé d'API 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();
}
}
Initialisation de la configuration
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;
}
Valeurs de clé
<endpoint>
- pour votre cloud Object Storage (disponible sur le tableau de bord IBM Cloud ). Pour plus d'informations sur les noeuds finaux, voir Noeuds finaux et emplacements de stockage.<api-key>
- clé api générée lors de la création des identifiants du service (l'accès en écriture est requis pour les exemples de création et de suppression)<resource-instance-id>
- iD de la ressource pour votre nuage Object Storage (disponible via IBM Cloud CLI ou IBM Cloud Dashboard )<location>
- emplacement par défaut de votre nuage Object Storage (doit correspondre à la région utilisée pour<endpoint>
)
Références SDK
Classes
Détermination de noeud final
Les méthodes ci-après peuvent être utilisées pour déterminer le noeud final de service en fonction de l'emplacement du compartiment, du type de noeud final (public ou privé) et de la région spécifique (facultatif). Pour plus d'informations sur les noeuds finaux, voir Noeuds finaux et emplacements de stockage.
/**
* 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;
}
Création d'un nouveau compartiment
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);
}
Création d'un compartiment avec une classe de stockage différente
Une liste de codes de mise à disposition valides pour LocationConstraint
peut être référencée dans le guide sur les classes de stockage.
cos.createBucket("sample", "us-vault"); // the name of the bucket, and the storage class (LocationConstraint)
Références SDK
Création d'un nouveau fichier texte
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);
}
Notez que lors de l'ajout de métadonnées personnalisées à un objet, un objet ObjectMetadata
doit être créé à l'aide du SDK et non pas en envoyant manuellement un en-tête personnalisé contenant x-amz-meta-{key}
. L'envoi
manuel peut engendrer des problèmes lors de l'authentification à l'aide de données d'identification HMAC.
Envoi par téléchargement d'un objet à partir d'un fichier
Cet exemple part du principe que le compartiment sample
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
);
Envoi par téléchargement d'un objet à l'aide d'un flux
Cet exemple part du principe que le compartiment sample
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
);
Vous pouvez également utiliser un CipherInputStream
pour chiffrer plus facilement le flux de données sans avoir à surcharger l'objet InputStream
existant.
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;
}
Réception par téléchargement d'un objet dans un fichier
Cet exemple part du principe que le compartiment sample
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
);
Réception par téléchargement d'un objet à l'aide d'un flux
Cet exemple part du principe que le compartiment sample
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
Copie d'objets
// 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
);
Références SDK
Classes
*Méthodes
putObject
Exception
La méthode putObject
peut générer l'exception suivante même si le téléchargement du nouvel objet a été effectué avec succès :
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
Cause première : les API JAXB sont considérées comme des API Java EE et ne sont plus contenues sur le chemin de classe par défaut dans Java SE 9.
Correctif : ajoutez l'entrée suivante au fichier pom.xml dans votre dossier de projet et reconditionnez votre projet.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Création de la liste des compartiments 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());
}
}
Références SDK
Classes
Méthodes
Création de la liste des éléments contenus dans un compartiment (v2)
L'objet AmazonS3 contient une méthode mise à jour pour répertorier le contenu (listObjectsV2). Cette méthode vous permet de limiter le nombre d'enregistrements renvoyés et d'extraire les enregistrements par lots. Cela peut s'avérer utile pour paginer vos résultats dans une application et améliorer les performances.
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!");
}
Références SDK
Classes
Méthodes
Obtention du contenu de fichier d'un élément particulier
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());
}
}
Références SDK
Classes
Méthodes
Suppression d'un élément d'un compartiment
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);
}
Références SDK
Méthodes
Suppression de plusieurs éléments d'un compartiment
La demande de suppression peut contenir un maximum de 1000 clés. Bien que cette méthode soit très utile pour réduire l'impact sur les performances par demande, il convient d'être prudent lors de la suppression d'un grand nombre de clés. Tenez compte également de la taille des objets de manière à obtenir de bonnes performances.
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());
}
}
Références SDK
Classes
Méthodes
Suppression d'un compartiment
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);
}
Références SDK
Méthodes
Procédure permettant de vérifier si un objet est accessible en lecture par le public
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());
}
}
Références SDK
Classes
Méthodes
Exécution d'un envoi par téléchargement en plusieurs parties
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));
}
}
Références SDK
Classes
- AbortMultipartUploadRequest
- CompleteMultipartUploadRequest
- InitiateMultipartUploadRequest
- InitiateMultipartUploadResult
- SdkClientException
- UploadPartRequest
- UploadPartResult
Méthodes
Création d'une politique de sauvegarde
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();
}
}
Lister une politique de sauvegarde
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();
}
}
Mettre en place une politique de sauvegarde
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();
}
}
Supprimer une politique de sauvegarde
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();
}
}
Création d'une chambre forte de sauvegarde
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();
}
}
Liste des chambres fortes de sauvegarde
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();
}
}
Obtenir des chambres fortes de sauvegarde
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();
}
}
Mise à jour des chambres fortes de sauvegarde
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();
}
}
Supprimer une chambre forte de sauvegarde
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();
}
}
Plages de récupération des listes
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();
}
}
Obtenir la plage de récupération
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();
}
}
Mise à jour de la plage de récupération
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();
}
}
Lancement d'une restauration
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();
}
}
Rétablissement des listes
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();
}
}
Obtenir les détails de la restauration
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();
}
}
Envoi par téléchargement d'objets plus volumineux à l'aide d'une classe TransferManager
TransferManager
simplifie les transferts de fichiers volumineux en incorporant automatiquement des envois par téléchargement en plusieurs parties chaque fois que cela est nécessaire lors de la définition des paramètres de configuration.
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();
}
Références SDK
Classes
Méthodes
Utilisation de Key Protect
Key Protect peut être ajouté à un compartiment de stockage pour chiffrer les données sensibles qui sont au repos dans le cloud.
Avant de commencer
Les éléments suivants sont nécessaires pour créer un compartiment avec Key Protect activé :
- Un service Key Protect doit être mis à disposition.
- Une clé racine doit être disponible (générée ou importée).
Extraction du CRN de clé racine
- Extrayez l'ID d'instance pour votre service Key Protect.
- Utilisez l'API Key Protect pour extraire toutes vos clés disponibles.
- Vous pouvez utiliser des commandes
curl
ou un client REST API, tel que Postman, pour accéder à l'API Key Protect.
- Vous pouvez utiliser des commandes
- Extrayez le CRN de la clé racine que vous utiliserez pour activer Key Protect sur votre compartiment. Le CRN se présentera comme suit :
crn:v1:bluemix:public:kms:us-south:a/3d624cd74a0dea86ed8efe3101341742:90b6a1db-0fe1-4fe9-b91e-962c327df531:key:0bg3e33e-a866-50f2-b715-5cba2bc93234
Création d'un compartiment avec Key Protect activé
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);
}
Valeurs de clé
<algorithm>
- L'algorithme de cryptage utilisé pour les nouveaux objets ajoutés au seau (la valeur par défaut est AES256 ).<root-key-crn>
- CRN de la clé racine obtenue auprès du service Key Protect.
Références SDK
Classes
Méthodes
Nouveaux en-têtes pour Key Protect
Les en-têtes supplémentaires ont été définis dans la classe 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 même section de l'implémentation de création de compartiment qui ajoute déjà les en-têtes d'instance de service IAM ajoutera les 2 nouveaux en-têtes de chiffrement :
//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());
}
}
Les objets ObjectListing
et HeadBucketResult
ont été mis à jour pour inclure les variables booléennes IBMSSEKPEnabled
et les variables de type chaîne IBMSSEKPCustomerRootKeyCrn
avec des méthodes
getter et setter. Cela permettra de stocker les valeurs des nouveaux en-têtes.
Opération GET sur un compartiment
public ObjectListing listObjects(String bucketName)
public ObjectListing listObjects(String bucketName, String prefix)
public ObjectListing listObjects(ListObjectsRequest listObjectsRequest)
La classe ObjectListing
requiert deux méthodes supplémentaires :
ObjectListing listing = s3client.listObjects(listObjectsRequest)
String KPEnabled = listing.getIBMSSEKPEnabled();
String crkId = listing.getIBMSSEKPCrkId();
Les en-têtes supplémentaires ont été définis dans la classe 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";
Le gestionnaire S3XmlResponseHandler est chargé de la déconversion de paramètres dans toutes les réponses XML. Une vérification a été ajoutée afin de s'assurer que le résultat est une instance de ObjectListing
et les en-têtes
extraits seront ajoutés à l'objet 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));
}
}
Opération HEAD sur un compartiment
Les en-têtes supplémentaires ont été définis dans la classe 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";
Ces variables sont remplies dans le gestionnaire 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();
Utilisation du Transfert haut débit Aspera
En installant la bibliothèque de transfert haut débit Aspera, vous pouvez utiliser des transferts de fichiers à haut débit dans votre application. La bibliothèque Aspera est un logiciel propriétaire (closed source), il s'agit donc d'une dépendance facultative pour le SDK COS (qui utilise une licence Apache).
Chaque session de transfert haut débit Aspera génère un processus ascp
individuel qui s'exécute sur la machine client pour effectuer le transfert. Assurez-vous que votre environnement de calcul puisse permettre l'exécution de ce
processus.
Vous aurez besoin d'instances des classes du client S3 et du gestionnaire de jetons IAM pour initialiser AsperaTransferManager
. L'objet s3Client
est requis afin d'obtenir des informations de connexion FASP pour le compartiment
cible COS. L'objet tokenManager
est requis pour permettre au SDK de la fonction Transfert haut débit Aspera de s'authentifier auprès du compartiment cible COS.
Initialisation de AsperaTransferManager
Avant d'initialiser AsperaTransferManager
, assurez-vous que les objets s3Client
et tokenManager
fonctionnent.
Il est conseillé d'utiliser TokenManager tokenManager = new DefaultTokenManager(new DelegateTokenProvider(apiKey));
et d'éviter .withTokenManager(tokenManager)
lors de la génération de AsperaTransferManager
avec AsperaTransferManagerBuilder
.
L'utilisation d'une seule session de transfert haut débit Aspera ne présente pas beaucoup d'avantages sauf si vous vous attendez à constater une mauvaise connexion ou une perte de paquet significative dans le réseau. Par conséquent, nous devons
indiquer à AsperaTransferManager
qu'il doit utiliser plusieurs sessions à l'aide de la classe AsperaConfig
. Cela permettra de fractionner le transfert en un certain nombre de sessions parallèles
qui envoient des blocs de données dont la taille est définie par la valeur threshold.
La configuration standard pour l'utilisation de plusieurs sessions doit être la suivante :
- Débit cible de 2500 Mbit/s
- Seuil de 100 Mo (il s'agit de la valeur recommandée pour la plupart des applications)
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();
Dans l'exemple ci-dessus, le SDK générera suffisamment de sessions pour tenter d'atteindre le taux cible de 2500 Mbit/s.
Sinon, la gestion de session peut aussi être configurée explicitement dans le SDK. Cela s'avère utile si vous souhaitez un contrôle plus précis de l'utilisation du réseau.
La configuration standard pour l'utilisation de plusieurs sessions explicites doit être la suivante :
- 2 ou 10 sessions
- Seuil de 100 Mo (il s'agit de la valeur recommandée pour la plupart des applications)
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();
Pour obtenir les meilleures performances dans la plupart des scénarios, utilisez toujours plusieurs sessions afin de minimiser le traitement associé à l'instanciation d'un transfert à grande vitesse à l'adresse Aspera. **Si votre capacité réseau est d'au moins 1 Gbps, vous devez utiliser 10 sessions. ** Des réseaux avec une bande passante inférieure doivent utiliser 2 sessions.
Valeurs de clé
API_KEY
- Clé d'API pour un utilisateur ou un ID de service doté des rôles Auteur ou Responsable.
Vous devez fournir une clé API IAM pour construire un AsperaTransferManager
. Les données d'identification HMAC ne sont PAS actuellement prises en charge. Pour plus d'informations sur IAM, cliquez ici.
Envoi par téléchargement d'un fichier
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();
Valeurs de clé
<bucket-name>
- nom du godet de votre instance de service Object Storage pour lequel l'option Aspera a été activée.<absolute-path-to-source-data>
- et le nom du fichier à télécharger sur Object Storage.<item-name>
- nom du nouvel objet ajouté au seau.
Réception par téléchargement d'un fichier
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();
Valeurs de clé
<bucket-name>
- nom du godet de votre instance de service Object Storage pour lequel l'option Aspera a été activée.<absolute-path-to-file>
- répertoire et nom du fichier à enregistrer à partir de Object Storage.<item-name>
- nom de l'objet dans le seau.
Envoi par téléchargement d'un répertoire
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();
Valeurs de clé
<bucket-name>
- nom du godet de votre instance de service Object Storage pour lequel l'option Aspera a été activée.<absolute-path-to-directory>
- répertoire des fichiers à télécharger sur Object Storage.<virtual-directory-prefix>
- nom du préfixe de répertoire à ajouter à chaque fichier lors du téléchargement. Utilisez une chaîne vide ou nulle pour envoyer par téléchargement les fichiers vers la racine du compartiment.
Réception par téléchargement d'un répertoire
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();
Valeurs de clé
<bucket-name>
- nom du godet de votre instance de service Object Storage pour lequel l'option Aspera a été activée.<absolute-path-to-directory>
- répertoire pour enregistrer les fichiers téléchargés à partir de Object Storage.<virtual-directory-prefix>
- nom du préfixe du répertoire de chaque fichier à télécharger. Utilisez une chaîne vide ou nulle pour recevoir par téléchargement tous les fichiers du compartiment.
Remplacement de la configuration de session pour chaque transfert
Vous pouvez remplacer les valeurs de configuration de plusieurs sessions pour chaque transfert en transmettant une instance de AsperaConfig
aux méthodes surchargées d'envoi par téléchargement et de réception par téléchargement.
A l'aide de AsperaConfig
, vous pouvez spécifier le nombre de sessions et la taille minimale de fichier par session.
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();
Surveillance de la progression du transfert
Le moyen le plus simple de surveiller la progression de vos transferts de fichiers/répertoires consiste à utiliser la propriété isDone()
qui renvoie la valeur true
lorsque votre transfert est terminé.
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);
}
Vous pouvez également vérifier si un transfert est mis en file d'attente pour traitement en appelant la méthode onQueue
sur le AsperaTransaction
. onQueue
renverra une valeur booléenne avec true
indiquant que le transfert est mis en file d'attente.
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);
}
Pour vérifier si un transfert est en cours, appelez la méthode progress dans 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);
}
Par défaut, un élément TransferProgress
est associé à chaque transfert. L'élément TransferProgress
signale le nombre d'octets transférés et le pourcentage d'octets transférés par rapport au nombre total d'octets à
transférer. Pour accéder à l'élément TransferProgress
d'un transfert, utilisez la méthode getProgress
dans 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);
}
Pour signaler le nombre d'octets transférés, appelez la méthode getBytesTransferred
sur TransferProgress
. Pour signaler le pourcentage d'octets transférés par rapport au nombre total d'octets à transférer, appelez
la méthode getPercentTransferred
sur 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);
}
Pause/Reprise/Annulation
Le SDK permet de gérer la progression des transferts de fichiers/répertoires via les méthodes suivantes de l'objet AsperaTransfer
:
pause()
resume()
cancel()
Il n'y a pas d'effets secondaires liés à l'appel de l'une ou l'autre des méthodes ci-dessus. Le nettoyage adéquat est géré par le SDK.
L'exemple suivant illustre une utilisation possible de ces méthodes :
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!");
Traitement des incidents liés à Aspera
Problème : les développeurs qui utilisent le SDK Oracle sur Linux ou Mac OS X peuvent rencontrer des pannes inattendues et silencieuses lors des transferts.
Cause : le code natif requiert ses propres gestionnaires de signaux, lesquels sont susceptibles d'écraser les gestionnaires de signaux de la machine virtuelle Java. Il peut être nécessaire d'utiliser la fonction de chaînage de signaux de la machine virtuelle Java.
IBM® Les utilisateurs de JDK ou de Microsoft® Windows ne sont pas concernés.
Solution : liez et chargez la bibliothèque de chaînage de signaux de la machine virtuelle Java.
-
Sous Linux, localisez la bibliothèque partagée
libjsig.so
et définissez la variable d'environnement suivante :LD_PRELOAD=<PATH_TO_SHARED_LIB>/libjsig.so
-
Sous Mac OS X, localisez la bibliothèque partagée
libjsig.dylib
et définissez les variables d'environnement suivantes :DYLD_INSERT_LIBRARIES=<PATH_TO_SHARED_LIB>/libjsig.dylib
DYLD_FORCE_FLAT_NAMESPACE=0
Consultez la documentation du JDK Oracle® pour plus d'informations sur le chaînage des signaux.
Problème : erreur UnsatisfiedLinkError
sous Linux.
Cause : le système ne peut pas charger les bibliothèques dépendantes. Des erreurs telles que la suivante peuvent être consignées dans les journaux d'application :
libfaspmanager2.so: libawt.so: cannot open shared object file: No such file or directory
Solution : définissez la variable d'environnement suivante :
LD_LIBRARY_PATH=<JAVA_HOME>/jre/lib/amd64/server:<JAVA_HOME>/jre/lib/amd64
Mise à jour de métadonnées
Il existe deux manières de mettre à jour les métadonnées sur un objet existant :
- Exécuter une demande
PUT
avec les nouvelles métadonnées et le contenu de l'objet d'origine - En exécutant une demande
COPY
avec les nouvelles métadonnées qui spécifient l'objet d'origine comme source de la copie
Utilisation de PUT pour mettre à jour les métadonnées
La demande PUT
écrase le contenu existant de l'objet, qui doit donc d'abord être téléchargé et rechargé avec les nouvelles métadonnées.
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);
}
Utilisation de COPY pour mettre à jour les métadonnées
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);
}
Utilisation d'Immutable Object Storage
Ajout d'une configuration de protection à un compartiment existant
Cette implémentation de l'opération PUT
utilise le paramètre de requête protection
pour définir les paramètres de conservation d'un compartiment existant. Cette opération vous permet de définir ou modifier la période
de conservation minimale, par défaut et maximale. Cette opération vous permet également de modifier l'état de protection du compartiment.
Les objets écrits dans un compartiment protégé ne peuvent pas être supprimés tant que la période de protection n'est pas arrivée à expiration et que les conservations légales associées à l'objet n'ont pas toutes été retirées. La valeur de conservation par défaut du compartiment est attribuée à un objet, sauf si une valeur spécifique à un objet est fournie lors de la création de l'objet. Lorsqu'ils sont écrasés, les objets des compartiments protégés auxquels plus aucune règle de conservation ne s'applique (la durée de conservation est arrivée à expiration et aucune conservation légale n'est associée à l'objet) sont de nouveau soumis à une durée de conservation. La nouvelle durée de conservation peut être fournie dans la demande d'écrasement de l'objet ou bien la durée de conservation par défaut du compartiment est attribuée à l'objet.
Les valeurs minimales et maximales prises en charge pour les paramètres de la période de conservation MinimumRetention
, DefaultRetention
et MaximumRetention
sont un minimum de 0 jour et un maximum de
365243 jours (1000 ans).
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);
}
Vérification de la protection d'un compartiment
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());
}
}
Envoi par téléchargement d'un objet protégé
Lorsqu'ils sont écrasés, les objets des compartiments protégés auxquels plus aucune règle de conservation ne s'applique (la durée de conservation est arrivée à expiration et aucune conservation légale n'est associée à l'objet) sont de nouveau soumis à une durée de conservation. La nouvelle durée de conservation peut être fournie dans la demande d'écrasement de l'objet ou bien la durée de conservation par défaut du compartiment est attribuée à l'objet.
Valeur | Type | Description |
---|---|---|
Retention-Period |
Entier non négatif (secondes) | Durée de conservation, exprimée en secondes, pendant laquelle stocker l'objet. L'objet ne peut être ni écrasé, ni supprimé tant que la durée de conservation n'est pas écoulée. Si cette zone et la zone Retention-Expiration-Date sont spécifiées, un code d'erreur 400 est renvoyé. Si aucune de ces deux zones n'est spécifiée, la période DefaultRetention du compartiment est utilisée. Zéro (0 ) est une valeur légale qui part
du principe que la durée de conservation minimale du compartiment est également fixée à 0 . |
Retention-expiration-date |
Date (format ISO 8601) | Date à laquelle la suppression ou la modification de l'objet devient légale. Vous pouvez uniquement spécifier cette zone ou bien la zone d'en-tête Retention-Period. Si ces deux zones sont spécifiées, un code d'erreur 400 est renvoyé. Si aucune de ces deux zones n'est spécifiée, la durée de conservation par défaut du compartiment est utilisée. |
Retention-legal-hold-id |
chaîne | Conservation légale unique à appliquer à l'objet. Une conservation légale est une chaîne comportant Y caractères. L'objet ne peut être ni écrasé ni supprimé tant que les conservations légales associées à l'objet n'ont pas toutes été retirées. |
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);
}
Ajout ou retrait d'une conservation légale dans un objet protégé
L'objet peut prendre en charge 100 conservations légales :
- Un identificateur de conservation légale est une chaîne comprise entre 1 et 64 caractères. Les caractères valables sont les lettres, les chiffres,
!
,_
,.
,*
,(
,)
,-
et'
. - Si la tentative d'ajout de la conservation légale spécifiée dépasse le seuil de 100 conservations légales affectées à l'objet, l'opération d'ajout échoue et un code d'erreur
400
est renvoyé. - Si un identificateur est trop long, il n'est pas ajouté à l'objet et un code d'erreur
400
est renvoyé. - Si un identificateur contient des caractères non valides, il n'est pas ajouté à l'objet et un code d'erreur
400
est renvoyé. - Si un identificateur est déjà en cours d'utilisation sur un objet, la conservation légale existante n'est pas modifiée et la réponse indique que l'identificateur était déjà utilisé et renvoie un code d'erreur
409
. - Si un objet ne comporte pas de métadonnées de durée de conservation, un code d'erreur
400
est renvoyé et l'ajout ou le retrait d'une conservation légale ne sont pas autorisés.
La présence d'un en-tête de durée de conservation est obligatoire, sinon, une erreur 400
est renvoyée.
L'utilisateur qui effectue l'ajout ou la suppression d'une conservation légale doit disposer des droits d'accès Manager
pour ce compartiment.
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);
}
Prolongement de la durée de conservation d'un objet protégé
La durée de conservation d'un objet ne peut être que prolongée. La valeur actuellement configurée ne peut pas être diminuée.
La valeur de prolongement de la conservation est définie de l'une des trois façons suivantes :
- En ajoutant une durée supplémentaire par rapport à la valeur en cours (
Additional-Retention-Period
ou méthode similaire) - En définissant une nouvelle période de prolongement, exprimée en secondes (
Extend-Retention-From-Current-Time
ou méthode similaire) - En définissant une nouvelle date d'expiration de la conservation de l'objet (
New-Retention-Expiration-Date
ou méthode similaire)
La durée de conservation en cours stockée dans les métadonnées de l'objet est soit augmentée de la durée supplémentaire indiquée, soit remplacée par la nouvelle valeur, en fonction du paramètre défini dans la demande extendRetention
.
Dans tous les cas, le paramètre de prolongement de la conservation est vérifié par rapport à la durée de conservation en cours et le paramètre de prolongement n'est accepté que si la durée de conservation mise à jour est supérieure à la
durée de conservation en cours.
Lorsqu'ils sont écrasés, les objets des compartiments protégés auxquels plus aucune règle de conservation ne s'applique (la durée de conservation est arrivée à expiration et aucune conservation légale n'est associée à l'objet) sont de nouveau soumis à une durée de conservation. La nouvelle durée de conservation peut être fournie dans la demande d'écrasement de l'objet ou bien la durée de conservation par défaut du compartiment est attribuée à l'objet.
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);
}
Création de la liste des conservations légales associées à un objet protégé
Cette opération renvoie les éléments suivants :
- La date de création de l'objet
- La durée de conservation, exprimée en secondes
- La date d'expiration de la conservation, calculée sur la base de la durée de conservation et de la date de création
- La liste des conservations légales
- L'identificateur de conservation légale
- L'horodatage correspondant à l'application de la conservation légale
Si aucune conservation légale n'est associée à l'objet, un élément LegalHoldSet
vide est renvoyé. Si aucune durée de conservation n'est spécifiée pour l'objet, un code d'erreur 404
est renvoyé.
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);
}
}
Créer un site Web statique hébergé
Cette opération requiert l'ajout d'une instruction d'importation:
import com.ibm.cloud.objectstorage.services.s3.model.model.BucketWebsiteConfiguration;
Cette opération fournit les éléments suivants lors de la configuration et requiert un client correctement configuré:
- Configuration de compartiment pour le suffixe (document d'index)
- Configuration de compartiment pour la clé (document d'erreur)
cosClient.setBucketWebsiteConfiguration("<bucket_name>", new BucketWebsiteConfiguration("index.html", "error.html"));
Etapes suivantes
Pour plus d'informations, voir le Javadoc. Le code source du projet se trouve dans le référentielGitHub.