Utilizzo di Java

IBM Cloud® Object Storage SDK for Java fornisce funzioni per utilizzare in modo ottimale IBM Cloud Object Storage.

IBM Cloud Object Storage SDK for Java è completo, con molte funzioni e funzionalità che vanno oltre l'ambito e lo spazio di questa guida. Per una documentazione dettagliata di classi e metodi, consulta la documentazione di Java. Il codice sorgente è disponibile nel repository GitHub.

Ottenimento dell'SDK

Il modo più facile per utilizzare IBM Cloud Object Storage SDK for Java consiste nell'usare Maven per gestire le dipendenze. Se non si ha familiarità con Maven, si può iniziare a lavorare utilizzando la guida Maven in 5 minuti.

Maven utilizza un file denominato pom.xml per specificare le librerie (e le relative versioni) necessarie per un progetto Java. Ecco un file pom.xml di esempio per utilizzare l'SDK IBM Cloud Object Storage Java per stabilire una connessione a Object Storage.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.cos</groupId>
    <artifactId>docs</artifactId>
    <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>

Creazione di un client e derivazione delle credenziali

Nel seguente esempio,un client cos viene creato e configurato fornendo informazioni di credenziali )chiave API e ID istanza del servizio). Questi valori possono anche essere derivati automaticamente da un file di credenziali o dalle variabili di ambiente.

Dopo aver generato una credenziale del servizio, il documento JSON risultante può essere salvato in ~/.bluemix/cos_credentials. L'SDK deriverà automaticamente le credenziali da questo file a meno che non vengano esplicitamente impostate altre credenziali durante la creazione del client. Se il file cos_credentials contiene le chiavi HMAC, il client esegue l'autenticazione con una firma, altrimenti utilizza la chiave API fornita tramite un token di connessione.

Se si esegue la migrazione da AWS S3, puoi anche derivare i dati delle credenziali da ~/.aws/credentials nel formato:

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

Se esistono ~/.bluemix/cos_credentials e ~/.aws/credentials, cos_credentials ha la precedenza.

Per ulteriori dettagli sulla creazione del client, vedi la documentazione Java.

Esempi di codici

Nel codice, è necessario rimuovere le parentesi angolari o qualsiasi altro carattere in eccesso fornito qui come illustrazione.

Iniziamo con una classe di esempio completa che verrà eseguita mediante della funzionalità di base ed esploriamo quindi le classi singolarmente. Questa classe CosExample elencherà gli oggetti in un bucket esistente, creerà un nuovo bucket ed elencherà quindi tutti i bucket nell'istanza del servizio.

Raccogli le informazioni richieste

  • bucketName e newBucketName sono stringhe univoche e indipendenti da DNS. Poiché i nomi dei bucket sono univoci nell'intero sistema, questi valori devono essere modificati se questo esempio viene eseguito più volte. Tieni presente che i nomi sono riservati per 10 - 15 minuti dopo l'eliminazione.
  • apiKey è il valore trovato nella credenziale di servizio come apikey.
  • serviceInstanceId è il valore trovato nella credenziale di servizio come resource_instance_id.
  • endpointUrl è un punto finale di servizio URL, comprensivo del protocollo https://. Questo non è il valore endpoints disponibile nella credenziale del servizio. Per ulteriori informazioni sugli endpoint, vedi Endpoint e ubicazioni di archiviazione.
  • storageClass è un codice di provisioning valido che corrisponde al valore endpoint. Questo viene quindi utilizzato come la variabile API S3 LocationConstraint.
  • location deve essere impostata sulla parte di ubicazione della storageClass. Per us-south-standard, sarà us-south. Questa variabile viene utilizzata solo per il calcolo delle firme HMAC, ma è obbligatoria per qualsiasi client, compreso questo esempio che utilizza una chiave 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();
        }
    }

Inizializzazione della configurazione

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;
}

Valori chiave

  • <endpoint>- endpoint pubblico per il cloud Object Storage (disponibile nella dashboard IBM Cloud ). Per ulteriori informazioni sugli endpoint, vedi Endpoint e ubicazioni di archiviazione.
  • <api-key>- chiave api generata durante la creazione delle credenziali del servizio (è richiesto l'accesso in scrittura per gli esempi di creazione e cancellazione)
  • <resource-instance-id>- iD risorsa per il cloud Object Storage (disponibile tramite IBM Cloud CLI o IBM Cloud Dashboard )
  • <location>- posizione predefinita per il cloud Object Storage (deve corrispondere alla regione utilizzata per <endpoint>)

Riferimenti SDK

Classi

Determinazione dell'endpoint

I metodi di seguito possono essere utilizzati per determinare l'endpoint del servizio in base all'ubicazione del bucket, al tipo di endpoint (pubblico o privato) e alla specifica regione (facoltativo). Per ulteriori informazioni sugli endpoint, vedi Endpoint e ubicazioni di archiviazione.

/**
* 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;
}

Creazione di un nuovo bucket

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);
}

Crea un bucket con una classe di archiviazione differente

È possibile che si faccia riferimento a un elenco di codici di provisioning validi per LocationConstraint nella guida alle classi di archiviazione.

cos.createBucket("sample", "us-vault"); // the name of the bucket, and the storage class (LocationConstraint)

Riferimenti SDK

Creazione di un nuovo file di testo

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);
}

Nota: quando aggiungi metadati personalizzati a un oggetto, è necessario creare un oggetto ObjectMetadata utilizzando l'SDK e non inviare manualmente un'intestazione personalizzata contenente x-amz-meta-{key}. Quest'ultima operazione può causare dei problemi quando si esegue l'autenticazione utilizzando credenziali HMAC.

Carica oggetto da un file

Questo esempio presume che il bucket sample esista.

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
);

Carica oggetto utilizzando un flusso

Questo esempio presume che il bucket sample esista.

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
);

In alternativa, è possibile utilizzare CipherInputStream per codificare più facilmente il flusso di dati senza dover sovraccaricare l'oggetto InputStream esistente.

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;
}

Scarica oggetto in un file

Questo esempio presume che il bucket sample esista.

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
);

Scarica oggetto utilizzando un flusso

Questo esempio presume che il bucket sample esista.

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 oggetti

// 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
);

Riferimenti SDK

Classi

*Metodi

putObject Eccezione

Il metodo putObject potrebbe lanciare la seguente eccezione anche se il caricamento del nuovo oggetto è avvenuto con successo:

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 radice: le API JAXB sono considerate API Java EE e non sono più contenute nel percorso classe predefinito in Java SE 9.

Correzione: aggiungi la seguente voce al file pom.xml nella tua cartella del progetto e riassembla il tuo progetto

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>

Elenca i bucket disponibili

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());
    }
}

Riferimenti SDK

Classi

Metodi

Elenca gli elementi in un bucket (v2)

L'oggetto AmazonS3 contiene un metodo aggiornato per elencare il contenuto (listObjectsV2). Questo metodo ti consente di limitare il numero di record restituiti e di richiamare i record in batch. Questo potrebbe essere utile per la paginazione dei tuoi risultati all'interno di un'applicazione e per migliorare le prestazioni.

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!");
}

Riferimenti SDK

Classi

Metodi

Ottieni il contenuto del file di uno specifico elemento

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());
    }
}

Riferimenti SDK

Classi

Metodi

Elimina un elemento da un bucket

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);
}

Riferimenti SDK

Metodi

Elimina più elementi da un bucket

La richiesta di eliminazione può contenere un massimo di 1000 chiavi che vuoi eliminare. Sebbene sia molto utile per ridurre le prestazioni per richiesta, occorre prestare attenzione quando si elimina un gran numero di chiavi. Tieni inoltre presente le dimensioni degli oggetti per assicurarti prestazioni adeguate.

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());
    }
}

Riferimenti SDK

Classi

Metodi

Elimina un bucket

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);
}

Riferimenti SDK

Metodi

Controlla se un oggetto è leggibile pubblicamente

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());
    }
}

Riferimenti SDK

Classi

Metodi

Esegui un caricamento in più parti

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));
    }
}

Riferimenti SDK

Classi

Metodi

Creazione di un criterio di backup

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();
        }
    }

Elencare un criterio di backup

    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();
            }
        }

Ottenere una politica di backup

    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();
            }
        }

Eliminare un criterio di backup

    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();
            }
        }

Creazione di un vault di backup

    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();
            }
        }

Elenco delle camere blindate di backup

    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();
            }
        }

Ottenere i vault di backup

    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();
            }
        }

Aggiornare i vault di backup

    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();
            }
        }

Eliminare un vault di backup

    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();
            }
        }

Elenco Gamme di recupero

    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();
            }
        }

Ottenere l'intervallo di recupero

    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();
            }
        }

Aggiornamento dell'intervallo di recupero

    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();
            }
        }

Avvio di un ripristino

    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();
            }
        }

Ripristino dell'elenco

    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();
           }

        }

Ottenere i dettagli del ripristino

    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();
           }

        }

Crea un nuovo bucket COS con blocco oggetto abilitato

    public static void createBucket(String bucketName, AmazonS3 _cosClient)
        {
            _cosClient.createBucket(bucketName);
            System.out.printf("Bucket: %s created!\n", bucketName);
        }

Imposta la configurazione del blocco oggetti con modalità di conformità sul bucket COS

    public static void putObjectLockConfiguration(String bucketName, AmazonS3 _cosClient)
        {
            DefaultRetention defRet = new DefaultRetention()
                    .withMode(ObjectLockRetentionMode.COMPLIANCE)
                    .withDays(1);
            ObjectLockRule objRule = new ObjectLockRule()
                            .withDefaultRetention(defRet);
            ObjectLockConfiguration objConfig = new ObjectLockConfiguration()
                            .withObjectLockEnabled(ObjectLockEnabled.ENABLED)
                            .withRule(objRule);
            SetObjectLockConfigurationRequest objSet = new SetObjectLockConfigurationRequest()
                            .withBucketName(BUCKET_NAME)
                            .withObjectLockConfiguration(objConfig);
            _cosClient.setObjectLockConfiguration(objSet);
            System.out.printf("Successfully added object lock cofiguration on : %s\n", bucketName);
        }

Imposta la configurazione del blocco degli oggetti con modalità di governance sul bucket COS

    public static void putObjectLockConfigurationWithGovernanceMode(String bucketName, AmazonS3 _cosClient)
        {
            DefaultRetention defRet = new DefaultRetention()
                    .withMode(ObjectLockRetentionMode.GOVERNANCE)
                    .withDays(1);
            ObjectLockRule objRule = new ObjectLockRule()
                            .withDefaultRetention(defRet);
            ObjectLockConfiguration objConfig = new ObjectLockConfiguration()
                            .withObjectLockEnabled(ObjectLockEnabled.ENABLED)
                            .withRule(objRule);
            SetObjectLockConfigurationRequest objSet = new SetObjectLockConfigurationRequest()
                            .withBucketName(BUCKET_NAME)
                            .withObjectLockConfiguration(objConfig);
            _cosClient.setObjectLockConfiguration(objSet);
            System.out.printf("Successfully added object lock cofiguration on : %s\n", bucketName);
        }

Ottieni la configurazione del blocco oggetti sul bucket COS

    public static void getObjectLockConfigurationWithGovernanceMode(String bucketName, AmazonS3 _cosClient)
        {
            GetObjectLockConfigurationRequest objReq = new GetObjectLockConfigurationRequest().withBucketName(BUCKET_NAME);
            GetObjectLockConfigurationResult objRes = _cosClient.getObjectLockConfiguration(objReq);
            ObjectLockConfiguration objLckConfig = objRes.getObjectLockConfiguration();
            ObjectLockRule objGetRule = objLckConfig.getRule();
            System.out.printf("ObjectLock Configuration : %s\n", objGetRule);

        }

Carica un oggetto con modalità di governance nel bucket COS

    public static void uploadFileWithGovernanceMode(String bucketName, String itemName, String fileText) {
            System.out.printf("Creating new item: %s\n", itemName);
            LocalDate date = LocalDate.of(2025, 11, 11);
            InputStream newStream = new ByteArrayInputStream(fileText.getBytes(Charset.forName("UTF-8")));
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(fileText.length());
            PutObjectRequest req = new PutObjectRequest(bucketName, itemName, newStream, metadata)
                                .withObjectLockMode("GOVERNANCE")
                                .withObjectLockRetainUntilDate(date);
            _cosClient.putObject(req);
            System.out.printf("Item: %s created!\n", itemName);
        }

Attiva la conservazione del blocco dell'oggetto con modalità di conformità sull'oggetto

    public static void putObjectLockRetention(String bucketName,String itemName, AmazonS3 _cosClient)
        {
            LocalDate date = LocalDate.of(2025, 11, 11);
            ObjectLockRetention objRet = new ObjectLockRetention()
                        .withMode("COMPLIANCE")
                        .withRetainUntilDate(date);
            SetObjectRetentionRequest objSet = new SetObjectRetentionRequest()
                        .withBucketName(BUCKET_NAME)
                        .withitemName(itemName)
                        .withRetention(objRet);
                        .withBypassGovernanceRetention(true);
            _cosClient.setObjectRetention(objSet);
            System.out.printf("Successfully added object retention on : %s\n", itemName);
        }

Attiva la conservazione del blocco dell'oggetto con modalità di governance sull'oggetto

    public static void putObjectLockRetentionWithGovernanceMode(String bucketName,String itemName, AmazonS3 _cosClient)
        {
            LocalDate date = LocalDate.of(2025, 11, 11);
            ObjectLockRetention objRet = new ObjectLockRetention()
                        .withMode("GOVERNANCE")
                        .withRetainUntilDate(date);
            SetObjectRetentionRequest objSet = new SetObjectRetentionRequest()
                        .withBucketName(BUCKET_NAME)
                        .withitemName(itemName)
                        .withRetention(objRet);
                        .withBypassGovernanceRetention(true);
            _cosClient.setObjectRetention(objSet);
            System.out.printf("Successfully added object retention on : %s\n", itemName);
        }

Ottieni il mantenimento del blocco dell'oggetto

    public static void getObjectLockRetentionWithGovernanceMode(String bucketName,String itemName, AmazonS3 _cosClient)
        {
            GetObjectRetentionRequest objReq = new GetObjectRetentionRequest()
                .withBucketName(BUCKET_NAME)
                .withitemName(itemName);
            GetObjectRetentionResult objRes1 = _cosClient.getObjectRetention(objReq);
            ObjectLockRetention objRet1 = objRes1.getRetention();
            System.out.printf("Retention : %s\n", objRet1);
        }

Eliminazione di un oggetto con modalità di governance del blocco oggetti utilizzando la governance di bypass

    public static void deleteObjectWithBypassGovernance(String bucketName, String itemName) {
            System.out.printf("Deleting item: %s\n", itemName);
            DeleteObjectRequest deleteRequest = new DeleteObjectRequest(BUCKET_NAME, Key)
                .withBypassGovernanceRetention(true);
            _cosClient.deleteObject(deleteRequest);
            System.out.printf("Item: %s deleted!\n", itemName);
        }

Carica oggetti più grandi utilizzando un gestore trasferimenti

TransferManager semplifica i trasferimenti di file di grandi dimensioni incorporando automaticamente dei caricamenti in più parti ogni qual volta è necessario impostando i parametri di configurazione.

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();
    }

Riferimenti SDK

Classi

Metodi

Utilizzo di Key Protect

Key Protect può essere aggiunto a un bucket di archiviazione per crittografare dati sensibili inattivi nel cloud.

Prima di cominciare

I seguenti elementi sono necessari per creare un bucket con Key-Protect abilitato:

Richiamo del CRN di chiave root

  1. Richiama l'ID istanza per il tuo servizio Key Protect
  2. Utilizza l'API Key Protect per richiamare tutte le tue chiavi disponibili
  3. Richiama il CRN della chiave root che utilizzerai per abilitare Key Protect sul tuo bucket. Il CRN sarà simile al seguente:

crn:v1:bluemix:public:kms:us-south:a/3d624cd74a0dea86ed8efe3101341742:90b6a1db-0fe1-4fe9-b91e-962c327df531:key:0bg3e33e-a866-50f2-b715-5cba2bc93234

Creazione di un bucket con Key Protect abilitato

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);
}

Valori chiave

  • <algorithm>- L'algoritmo di crittografia utilizzato per i nuovi oggetti aggiunti al bucket (l'impostazione predefinita è AES256 ).
  • <root-key-crn>- CRN della Root Key ottenuta dal servizio Key Protect.

Riferimenti SDK

Classi

Metodi

Nuove intestazioni per Key Protect

Nella classe Headers sono state definite delle intestazioni aggiuntive:

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 stessa sezione dell'implementazione di creazione del bucket che già aggiunge le intestazioni dell'istanza del servizio IAM aggiungerà le 2 nuove intestazioni di crittografia:

//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());
    }
}

Gli oggetti ObjectListing e HeadBucketResult sono stati aggiornati per includere le variabili boolean IBMSSEKPEnabled e string IBMSSEKPCustomerRootKeyCrn con metodi getter e setter. Memorizzeranno i valori delle nuove intestazioni.

Bucket GET

public ObjectListing listObjects(String bucketName)
public ObjectListing listObjects(String bucketName, String prefix)
public ObjectListing listObjects(ListObjectsRequest listObjectsRequest)

La classe ObjectListing richiederà 2 metodi aggiuntivi:

ObjectListing listing = s3client.listObjects(listObjectsRequest)
String KPEnabled = listing.getIBMSSEKPEnabled();
String crkId = listing.getIBMSSEKPCrkId();

Le intestazioni aggiuntive sono state definite all'interno della 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";

L'S3XmlResponseHandler che è responsabile dell'annullamento del marshalling di tutte le risposte xml. È stato aggiunto un controllo che il risultato sia un'istanza di ObjectListing e che le intestazioni richiamate verranno aggiunte all'oggetto 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));
        }
}

Bucket HEAD

Le intestazioni aggiuntive sono state definite all'interno della 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";

Queste variabili sono compilate nell'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();

Utilizzo del trasferimento ad alta velocità Aspera

Installando la libreria di trasferimento ad alta velocità Aspera, puoi utilizzare i trasferimenti di file ad alta velocità all'interno della tua applicazione. La libreria Aspera è closed-source e, pertanto, una dipendenza facoltativa per l'SDK COS (che utilizza una licenza Apache).

Ogni sessione di trasferimento ad alta velocità Aspera genera un singolo processo ascp che viene eseguito sulla macchina client per eseguire il trasferimento. Assicurati che il tuo ambiente di calcolo possa consentire l'esecuzione di questo processo.

Ti serviranno delle istanze delle classi del client S3 e del gestore dei token IAM per inizializzare l'AsperaTransferManager. s3Client è necessario per ottenere le informazioni sulla connessione FASP per il bucket di destinazione COS. tokenManager è necessario per consentire all'SDK di trasferimento ad alta velocità Aspera di eseguire l'autenticazione presso il bucket di destinazione COS.

Inizializzazione di AsperaTransferManager

Prima di inizializzare AsperaTransferManager, assicurati di disporre di oggetti s3Client e tokenManager funzionanti.

Si consiglia di utilizzare TokenManager tokenManager = new DefaultTokenManager(new DelegateTokenProvider(apiKey)); ed evitare .withTokenManager(tokenManager) quando si crea AsperaTransferManager con AsperaTransferManagerBuilder.

L'utilizzo di una singola sessione del trasferimento ad alta velocità Aspera non offre molti vantaggi, a meno che tu non preveda un rumore o una perdita di pacchetti notevoli nella rete. Dobbiamo quindi indicare a AsperaTransferManager di utilizzare più sessioni utilizzando la classe AsperaConfig. Questo suddividerà il trasferimento in diverse sessioni parallele che inviano blocchi di dati la cui dimensione è definita dal valore threshold.

La tipica configurazione per l'utilizzo di più sessioni dovrebbe essere:

  • Velocità di destinazione di 2500 MBps
  • Soglia di 100 MB (questo è il valore consigliato per la maggior parte delle applicazioni)
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();

Nell'esempio sopra riportato, l'SDK genererà un numero sufficiente di sessioni per provare a raggiungere la velocità di destinazione di 2500 MBps.

In alternativa, la gestione delle sessioni può essere configurata esplicitamente nell'SDK. Ciò è utile nei casi in cui si voglia un controllo più preciso sull'utilizzo della rete.

La tipica configurazione per l'utilizzo di più sessioni esplicito dovrebbe essere:

  • 2 o 10 sessioni
  • Soglia di 100 MB (questo è il valore consigliato per la maggior parte delle applicazioni)
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();

Per ottenere le migliori prestazioni nella maggior parte degli scenari, utilizzare sempre sessioni multiple per ridurre al minimo l'elaborazione associata all'istanziazione di un trasferimento ad alta velocità Aspera. Se la tua capacità di rete è di almeno 1 Gbps devi utilizzare 10 sessioni. Reti con una larghezza di banda inferiore devono utilizzare due sessioni.

Valori chiave

  • API_KEY - una chiave API per un ID servizio o utente con ruoli di Writer (Scrittore) o Manager (Gestore)

È necessario fornire una chiave API IAM per costruire un sito AsperaTransferManager. Le credenziali HMAC NON sono attualmente supportate. Per ulteriori informazioni su IAM, fai clic qui.

Caricamento file

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();

Valori chiave

  • <bucket-name>- nome del bucket nell'istanza del servizio Object Storage che ha abilitato Aspera.
  • <absolute-path-to-source-data>- e il nome del file da caricare su Object Storage.
  • <item-name>- nome del nuovo oggetto aggiunto al bucket.

Scarica file

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();

Valori chiave

  • <bucket-name>- nome del bucket nell'istanza del servizio Object Storage che ha abilitato Aspera.
  • <absolute-path-to-file>- directory e nome del file da salvare da Object Storage.
  • <item-name>- nome dell'oggetto nel bucket.

Caricamento directory

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();

Valori chiave

  • <bucket-name>- nome del bucket nell'istanza del servizio Object Storage che ha abilitato Aspera.
  • <absolute-path-to-directory>- dei file da caricare su Object Storage.
  • <virtual-directory-prefix>- nome del prefisso della directory da aggiungere a ogni file al momento del caricamento. Utilizza una stringa null o vuota per caricare i file nella root del bucket.

Scaricamento directory

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();

Valori chiave

  • <bucket-name>- nome del bucket nell'istanza del servizio Object Storage che ha abilitato Aspera.
  • <absolute-path-to-directory>- per salvare i file scaricati da Object Storage.
  • <virtual-directory-prefix>- nome del prefisso della directory di ciascun file da scaricare. Utilizza una stringa null o vuota per scaricare tutti i file nel bucket.

Sovrascrittura della configurazione di sessione per ogni singolo trasferimento

Puoi sovrascrivere i valori della configurazione a più sessioni per ogni singolo trasferimento passando un'istanza di AsperaConfig ai metodi sovraccaricati di caricamento e download. Utilizzando AsperaConfig, puoi specificare il numero di sessioni e la dimensione di soglia di file minima per ogni sessione.

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();

Monitoraggio dell'avanzamento del trasferimento

Il modo più semplice per monitorare l'avanzamento dei tuoi trasferimenti di file/directory consiste nell'utilizzare la proprietà isDone() che restituisce true quando il tuo trasferimento è completo.

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);
}

È anche possibile verificare se un trasferimento è accodato per l'elaborazione richiamando il metodo onQueue su AsperaTransaction. onQueue restituirà un valore booleano con true che indica che il trasferimento è accodato.

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);
}

Per controllare se un trasferimento è in corso, richiama il metodo progress in 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);
}

Ogni trasferimento avrà, per impostazione predefinita, un TransferProgress collegato a esso. Il TransferProgress notificherà il numero di byte trasferito e la percentuale trasferita dei byte totali da trasferire. Per accedere al TransferProgress di un trasferimento, utilizza il metodo getProgress in 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);
}

Per notificare il numero di byte trasferito, richiama il metodo getBytesTransferred su TransferProgress. Per notificare la percentuale trasferita dei byte totali da trasferire, richiama il metodo getPercentTransferred su 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);
}

Metti in pausa/Riprendi/Annulla

L'SDK consente di gestire l'avanzamento dei trasferimenti di file/directory mediante i seguenti metodi dell'oggetto AsperaTransfer:

  • pause()
  • resume()
  • cancel()

Il richiamo dei metodi sopra indicati non ha alcun effetto collaterale. Adeguate attività di ripulitura e manutenzione sono gestite dall'SDK.

Il seguente esempio mostra un uso possibile per questi metodi:

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!");

Risoluzione dei problemi di Aspera

Problema: gli sviluppatori che utilizzano Oracle JDK su Linux o Mac OS X potrebbero riscontrare degli arresti anomali imprevisti e non notificati durante i trasferimenti

Causa: il codice nativo richiede dei propri gestori di segnale che potrebbero sovrascrivere i gestori di segnale di JVM. Potrebbe essere necessario utilizzare la funzione di concatenamento dei segnali di JVM.

IBM® Gli utenti di JDK o di Microsoft® Windows non sono interessati.

Soluzione: collega e carica la libreria di concatenamento dei segnali di JVM.

  • Su Linux, individua la libreria condivisa libjsig.so e imposta la seguente variabile di ambiente:

    • LD_PRELOAD=<PATH_TO_SHARED_LIB>/libjsig.so
  • Su Mac OS X, individua la libreria condivisa libjsig.dylib e imposta le seguenti variabili di ambiente:

    • DYLD_INSERT_LIBRARIES=<PATH_TO_SHARED_LIB>/libjsig.dylib
    • DYLD_FORCE_FLAT_NAMESPACE=0

Per ulteriori informazioni sul concatenamento dei segnali, visitate il sito Oracle® Documentazione JDK.

Problema: UnsatisfiedLinkError su Linux

Causa: il sistema non è in grado di caricare le librerie dipendenti. Errori come il seguente potrebbero essere riscontrati nei log dell'applicazione:

libfaspmanager2.so: libawt.so: cannot open shared object file: No such file or directory

Soluzione: imposta la seguente variabile di ambiente:

LD_LIBRARY_PATH=<JAVA_HOME>/jre/lib/amd64/server:<JAVA_HOME>/jre/lib/amd64

Aggiornamento dei metadati

Esistono due modi per aggiornare i metadati in un oggetto esistente:

  • Una richiesta PUT con i nuovi metadati e il contenuto dell'oggetto originale
  • L'esecuzione di una richiesta COPY con i nuovi metadati che specifica l'oggetto originale come origine della copia

Utilizzo di PUT per aggiornare i metadati

La richiesta di PUT sovrascrive il contenuto esistente dell'oggetto, che deve quindi essere prima scaricato e ricaricato con i nuovi metadati.

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);
}

Utilizzo di COPY per aggiornare i metadati

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);
}

Utilizzo di Immutable Object Storage

Aggiunta di una configurazione di protezione ad un bucket esistente

Questa implementazione dell'operazione PUT utilizza il parametro di query protection per impostare i parametri di conservazione per un bucket esistente. Questa operazione ti consente di impostare o modificare il periodo di conservazione minimo, predefinito e massimo. Questa operazione ti consente anche di modificare lo stato di protezione del bucket.

Gli oggetti scritti in un bucket protetto non possono essere eliminati fino a quando il periodo di protezione non è scaduto e tutte le conservazioni a fini legali sull'oggetto non sono stati rimosse. A un oggetto viene dato il valore di conservazione predefinito del bucket, a meno che non venga fornito un valore specifico per l'oggetto quando l'oggetto viene creato. Gli oggetti nei bucket protetti che non sono più sottoposti a conservazione (il periodo di conservazione è scaduto e l'oggetto non ha alcuna conservazione a fini legali), quando vengono sovrascritti sono di nuovo sottoposti a conservazione. Il nuovo periodo di conservazione può essere fornito come parte della richiesta di sovrascrittura dell'oggetto, altrimenti all'oggetto verrà assegnato il tempo di conservazione predefinito del bucket.

I valori minimi e massimi supportati per le impostazioni del periodo di conservazione MinimumRetention, DefaultRetention e MaximumRetention sono un minimo di 0 giorni e un massimo di 365243 giorni (1000 anni).

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);
}

Controlla la protezione su un bucket

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());
    }
}

Carica un oggetto protetto

Gli oggetti nei bucket protetti che non sono più sottoposti a conservazione (il periodo di conservazione è scaduto e l'oggetto non ha alcuna conservazione a fini legali), quando vengono sovrascritti sono di nuovo sottoposti a conservazione. Il nuovo periodo di conservazione può essere fornito come parte della richiesta di sovrascrittura dell'oggetto, altrimenti all'oggetto verrà assegnato il tempo di conservazione predefinito del bucket.

Valore Immettere Descrizione
Retention-Period Numero intero non negativo (secondi) Il periodo di conservazione da memorizzare sull'oggetto, in secondi. L'oggetto non può essere sovrascritto o eliminato finché l'intervallo di tempo specificato nel periodo di conservazione non è trascorso. Se vengono specificati questi campo e Retention-Expiration-Date, viene restituito un errore 400. Se non viene specificato nessuno di questi due valori, verrà utilizzato il periodo DefaultRetention del bucket. Zero (0) è un valore consentito, presumendo che il periodo di conservazione minimo del bucket sia anch'esso 0.
Retention-expiration-date Data (formato ISO 8601) Data in cui sarà consentito eliminare o modificare l'oggetto. Puoi specificare solo questo valore oppure l'intestazione Retention-Period. Se vengono specificati entrambi, verrà restituito un errore 400. Se non viene specificato nessuno di questi due valori, verrà utilizzato il periodo DefaultRetention del bucket.
Retention-legal-hold-id stringa Una singola conservazione a fini legali da applicare all'oggetto. Una conservazione a fini legali è una stringa di caratteri di lunghezza Y. L'oggetto non può essere sovrascritto o eliminato finché non sono state rimosse tutte le conservazioni a fini legali a esso associate.
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);
}

Estendi il periodo di conservazione di un oggetto protetto

Il periodo di conservazione di un oggetto può solo essere esteso. Non può essere ridotto rispetto al valore attualmente configurato.

Il valore di espansione della conservazione è impostato in uno di tre possibili modi:

  • ulteriore tempo dal valore corrente (Additional-Retention-Period o metodo simile)
  • nuovo periodo di estensione in secondi (Extend-Retention-From-Current-Time o metodo simile)
  • nuova data di scadenza della conservazione dell'oggetto (New-Retention-Expiration-Date o metodo simile)

Il periodo di conservazione attuale memorizzato nei metadati dell'oggetto viene aumentato in misura equivalente al tempo aggiuntivo indicato oppure sostituito con il nuovo valore, a seconda del parametro impostato nella richiesta extendRetention. In tutti i casi, il parametro di estensione della conservazione viene controllato rispetto al periodo di conservazione attuale e il parametro esteso viene accettato solo se il periodo di conservazione aggiornato è più grande del periodo di conservazione attuale.

Gli oggetti nei bucket protetti che non sono più sottoposti a conservazione (il periodo di conservazione è scaduto e l'oggetto non ha alcuna conservazione a fini legali), quando vengono sovrascritti sono di nuovo sottoposti a conservazione. Il nuovo periodo di conservazione può essere fornito come parte della richiesta di sovrascrittura dell'oggetto, altrimenti all'oggetto verrà assegnato il tempo di conservazione predefinito del bucket.

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);
}

Elenca le conservazioni a fini legali su un oggetto protetto

Questa operazione restituisce:

  • La data di creazione dell'oggetto
  • Il periodo di conservazione dell'oggetto in secondi
  • Data di scadenza della conservazione calcolata sulla base del periodo e della data di creazione
  • Elenco delle conservazioni a fini legali
  • Identificativo della conservazione a fini legali
  • Data/ora di quando è stata applicata la conservazione a fini legali

Se non ci sono conservazioni a fini legali sull'oggetto, viene restituito un LegalHoldSet vuoto. Se non c'è alcun periodo di conservazione specificato sull'oggetto, viene restituito un errore 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);
    }
}

Crea un sito web statico ospitato

Questa operazione richiede l'aggiunta di un'istruzione di importazione:

import com.ibm.cloud.objectstorage.services.s3.model.model.BucketWebsiteConfiguration;

Questa operazione fornisce quanto segue alla configurazione e richiede un client configurato correttamente:

  • Configurazione bucket per suffisso (documento indice)
  • Configurazione bucket per la chiave (documento di errore)
cosClient.setBucketWebsiteConfiguration("<bucket_name>", new BucketWebsiteConfiguration("index.html", "error.html"));

Passi successivi

Per ulteriori informazioni, consultare il Javadoc. Il codice sorgente per il progetto è disponibile nel repositoryGitHub.