Usando o SDK IBM Cloud® Object Storage para Java
Fim do suporte em 6 de agosto de 2027. O SDK v1 do COS IBM Cloud® Object Storage ) atingirá o fim do suporte em 6 de agosto de 2027. Após essa data, ele não receberá mais atualizações, correções de segurança nem novas versões. Recomendamos a migração para o SDK do IBM Cloud Object Storage Java v2, que oferece melhor desempenho, segurança aprimorada, APIs modernas e suporte contínuo em IBM.
Use o SDK IBM Cloud® Object Storage para Java para criar clientes, obter credenciais, fazer upload de objetos grandes e gerenciar buckets com o Key Protect e o Aspera.
O IBM Cloud Object Storage SDK for Java é abrangente, com muitas capacidades e recursos que excedem o escopo e o espaço deste guia. Para obter a documentação detalhada de classe o método, consulte o Javadoc. O código-fonte pode ser localizado no Repositório GitHub.
Obtendo o SDK
A maneira mais fácil de usar o IBM Cloud Object Storage Java SDK é usar o Maven para gerenciar dependências. Se você não estiver familiarizado com o Maven, pode começar a usá-lo com o guia “Maven em 5 minutos ”.
O Maven usa um arquivo chamado pom.xml para especificar as bibliotecas (e suas versões) necessárias para um projeto Java. Aqui está um exemplo de arquivo pom.xml para usar o IBM Cloud Object Storage Java SDK para conexão
com o 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>
Criando um cliente e credenciais de fornecimento
No exemplo a seguir, um cliente cos é criado e configurado fornecendo informações de credenciais (Chave de API e ID da instância de serviço). Esses valores também podem ser originados automaticamente de um arquivo de credenciais
ou de variáveis de ambiente.
Depois de gerar uma Credencial de serviço, o documento JSON resultante pode ser salvo em ~/.bluemix/cos_credentials. O SDK obtém automaticamente
as credenciais deste arquivo, a menos que outras credenciais sejam definidas explicitamente durante a criação do cliente. Se o arquivo cos_credentials contiver chaves HMAC, o cliente será autenticado com uma assinatura, caso contrário,
o cliente usará a chave de API fornecida para autenticar usando um token de acesso.
Se estiver migrando do AWS S3, também será possível originar os dados de credenciais de ~/.aws/credentials no formato:
[default]
aws_access_key_id = {API_KEY}
aws_secret_access_key = {SERVICE_INSTANCE_ID}
Se ambos, ~/.bluemix/cos_credentials e ~/.aws/credentials, existirem, cos_credentials terá a preferência.
Para obter mais detalhes sobre a construção do cliente, consulte o Javadoc.
Exemplos de código
Em seu código, deve-se remover os colchetes ou quaisquer outros caracteres em excesso que são fornecidos aqui como ilustração.
Vamos começar com uma classe de exemplo completa que demonstra algumas funcionalidades básicas e, em seguida, explorar as classes individualmente. Essa classe CosExample lista os objetos em um bucket existente, cria um novo bucket
e, em seguida, lista todos os buckets na instância do serviço.
Reunir informações necessárias
bucketNameenewBucketNamesão sequências exclusivas e protegidas por DNS. Como os nomes dos depósitos são exclusivos em todo o sistema, esses valores precisarão ser mudados se este exemplo for executado múltiplas vezes. Observe que os nomes ficam reservados por 10 a 15 minutos após a exclusão.apiKeyé o valor encontrado na Credencial de Serviço comoapikey.serviceInstanceIdé o valor encontrado na Credencial de Serviço comoresource_instance_id.endpointUrlé uma URL de ponto de extremidade do serviço, incluindo o protocolohttps://. Esse não é o valorendpointslocalizado na Credencial de serviço. Para obter mais informações sobre terminais, consulte Terminais e locais de armazenamento.storageClassé um código de fornecimento válido que corresponde ao valorendpoint. Isso é, então, usado como a variávelLocationConstraintda API S3.locationdeve ser configurado como a parte de local dostorageClass. Paraus-south-standard, esse seriaus-south. Essa variável é usada somente para o cálculo de assinaturas HMAC, mas é necessária para qualquer cliente, incluindo este exemplo que usa uma chave de API do 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();
}
}
Inicializando a configuração
private static String COS_ENDPOINT = "<endpoint>"; // eg "https://s3.us.cloud-object-storage.appdomain.cloud"
private static String COS_API_KEY_ID = "<api-key>"; // eg "0viPHOY7LbLNa9eLftrtHPpTjoGv6hbLD1QalRXikliJ"
private static String COS_AUTH_ENDPOINT = "https://iam.cloud.ibm.com/identity/token";
private static String COS_SERVICE_CRN = "<resource-instance-id>"; // "crn:v1:bluemix:public:cloud-object-storage:global:a/<CREDENTIAL_ID_AS_GENERATED>:<SERVICE_ID_AS_GENERATED>::"
private static String COS_BUCKET_LOCATION = "<location>"; // eg "us"
public static void main(String[] args)
{
SDKGlobalConfiguration.IAM_ENDPOINT = COS_AUTH_ENDPOINT;
try {
_cos = createClient(COS_API_KEY_ID, COS_SERVICE_CRN, COS_ENDPOINT, COS_BUCKET_LOCATION);
} catch (SdkClientException sdke) {
System.out.printf("SDK Error: %s\n", sdke.getMessage());
} catch (Exception e) {
System.out.printf("Error: %s\n", e.getMessage());
}
}
public static AmazonS3 createClient(String api_key, String service_instance_id, String endpoint_url, String location)
{
AWSCredentials credentials = new BasicIBMOAuthCredentials(api_key, service_instance_id);
ClientConfiguration clientConfig = new ClientConfiguration().withRequestTimeout(5000);
clientConfig.setUseTcpKeepAlive(true);
AmazonS3 cos = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials))
.withEndpointConfiguration(new EndpointConfiguration(endpoint_url, location)).withPathStyleAccessEnabled(true)
.withClientConfiguration(clientConfig).build();
return cos;
}
Valores da chave
<endpoint>- endpoint público para o seu Object Storage na nuvem (disponível no Painel do IBM Cloud). Para obter mais informações sobre terminais, consulte Terminais e locais de armazenamento.<api-key>- chave de API gerada ao criar as credenciais do serviço (é necessário acesso de gravação para os exemplos de criação e exclusão)<resource-instance-id>- ID do recurso para o seu Object Storage na nuvem (disponível por meio da CLI do IBM Cloud ou do Painel do IBM Cloud)<location>- localização padrão para o seu Object Storage na nuvem (deve corresponder à região utilizada para<endpoint>)
Referências do SDK.
Classes
Determinando o terminal
Os métodos a seguir podem ser usados para determinar o terminal em serviço com base no local do depósito, tipo de terminal (público ou privado) e região específica (opcional). Para obter mais informações sobre terminais, consulte Terminais e locais de armazenamento.
/**
* 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;
}
Criando um novo depósito
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);
}
Criar um depósito com uma classe de armazenamento diferente
Uma lista de códigos de fornecimento válidos para LocationConstraint pode ser referenciada no guia de Classes de armazenamento.
cos.createBucket("sample", "us-vault"); // the name of the bucket, and the storage class (LocationConstraint)
Referências do SDK.
Criando um novo arquivo de texto
public static void createTextFile(String bucketName, String itemName, String fileText) {
System.out.printf("Creating new item: %s\n", itemName);
byte[] arr = fileText.getBytes(StandardCharsets.UTF_8);
InputStream newStream = new ByteArrayInputStream(arr);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(arr.length);
PutObjectRequest req = new PutObjectRequest(bucketName, itemName, newStream, metadata);
_cos.putObject(req);
System.out.printf("Item: %s created!\n", itemName);
}
Observe que ao incluir metadados customizados em um objeto, é necessário criar um objeto ObjectMetadata usando o SDK e não enviar manualmente um cabeçalho customizado contendo x-amz-meta-{key}. O último pode causar
problemas ao autenticar usando credenciais HMAC.
Fazer upload do objeto de um arquivo
Este exemplo assume que o depósito 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
);
Fazer upload do objeto usando um fluxo
Este exemplo assume que o depósito 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
);
Como alternativa, é possível usar um CipherInputStream para criptografar mais facilmente o fluxo de dados sem precisar sobrecarregar o objeto InputStream existente.
public CipherInputStream encryptStream(InputStream inputStream) {
// Generate key
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey aesKey = kgen.generateKey();
// Encrypt cipher
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
CipherInputStream cis = new CipherInputStream(inputStream, cipher);
return cis;
}
Fazer download do objeto para um arquivo
Este exemplo assume que o depósito 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
);
Fazer download do objeto usando um fluxo
Este exemplo assume que o depósito 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
Copiar objetos
// copy an object within the same Bucket
cos.copyObject( // copy the Object, passing…
"sample", // the name of the Bucket in which the Object to be copied is stored,
"myFile.txt", // the name of the Object being copied from the source Bucket,
"sample", // the name of the Bucket in which the Object to be copied is stored,
"myFile.txt.backup" // and the new name of the copy of the Object to be copied
);
// copy an object between two Buckets
cos.copyObject( // copy the Object, passing…
"sample", // the name of the Bucket from which the Object will be copied,
"myFile.txt", // the name of the Object being copied from the source Bucket,
"backup", // the name of the Bucket to which the Object will be copied,
"myFile.txt" // and the name of the copied Object in the destination Bucket
);
Referências do SDK.
Classes
*Métodos
putObject Exceção
O método putObject pode lançar a seguinte exceção, mesmo que o upload do novo objeto tenha sido bem-sucedido:
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 raiz: as APIs JAXB são consideradas como APIs do Java EE e não estão mais contidas no caminho de classe padrão no Java SE 9.
Correção: inclua a entrada a seguir no arquivo pom.xml em sua pasta de projeto e reempacote seu projeto
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Listar depósitos disponíveis
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());
}
}
Referências do SDK.
Classes
Métodos
Listar itens em um depósito (v2)
O objeto AmazonS3 contém um método atualizado para listar o conteúdo (listObjectsV2). Esse método permite limitar o número de registros que são retornados e recuperar os registros em lotes. Isso pode ser útil para paginar seus resultados em um aplicativo e melhorar o desempenho.
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!");
}
Referências do SDK.
Classes
Métodos
Obter conteúdo do arquivo de um item específico
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());
}
}
Referências do SDK.
Classes
Métodos
Excluir um item de um depósito
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);
}
Referências do SDK.
Métodos
Excluir múltiplos itens de um depósito
A solicitação de exclusão pode conter um máximo de 1000 chaves que você deseja excluir. Embora isso seja muito útil para reduzir a perda de desempenho por solicitação, tenha cuidado ao excluir um grande número de chaves. Além disso, leve em conta os tamanhos dos objetos para assegurar o desempenho adequado.
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());
}
}
Referências do SDK.
Classes
Métodos
Excluir um depósito
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);
}
Referências do SDK.
Métodos
Verificar se um objeto é legível publicamente
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());
}
}
Referências do SDK.
Classes
Métodos
Executar um upload de múltiplas partes
public static void multiPartUpload(String bucketName, String itemName, String filePath) {
File file = new File(filePath);
if (!file.isFile()) {
System.out.printf("The file '%s' does not exist or is not accessible.\n", filePath);
return;
}
System.out.printf("Starting multi-part upload for %s to bucket: %s\n", itemName, bucketName);
InitiateMultipartUploadResult mpResult = _cos.initiateMultipartUpload(new InitiateMultipartUploadRequest(bucketName, itemName));
String uploadID = mpResult.getUploadId();
//begin uploading the parts
//min 5MB part size
long partSize = 1024 * 1024 * 5;
long fileSize = file.length();
long partCount = ((long)Math.ceil(fileSize / partSize)) + 1;
List<PartETag> dataPacks = new ArrayList<PartETag>();
try {
long position = 0;
for (int partNum = 1; position < fileSize; partNum++) {
partSize = Math.min(partSize, (fileSize - position));
System.out.printf("Uploading to %s (part %s of %s)\n", name, partNum, partCount);
UploadPartRequest upRequest = new UploadPartRequest()
.withBucketName(bucketName)
.withKey(itemName)
.withUploadId(uploadID)
.withPartNumber(partNum)
.withFileOffset(position)
.withFile(file)
.withPartSize(partSize);
UploadPartResult upResult = _cos.uploadPart(upRequest);
dataPacks.add(upResult.getPartETag());
position += partSize;
}
//complete upload
_cos.completeMultipartUpload(new CompleteMultipartUploadRequest(bucketName, itemName, uploadID, dataPacks));
System.out.printf("Upload for %s Complete!\n", itemName);
} catch (SdkClientException sdke) {
System.out.printf("Multi-part upload aborted for %s\n", itemName);
System.out.printf("Upload Error: %s\n", sdke.getMessage());
_cos.abortMultipartUpload(new AbortMultipartUploadRequest(bucketName, itemName, uploadID));
}
}
Referências do SDK.
Classes
- AbortMultipartUploadRequest
- CompleteMultipartUploadRequest
- InitiateMultipartUploadRequest
- InitiateMultipartUploadResult
- SdkClientException
- UploadPartRequest
- UploadPartResult
Métodos
Criação de uma política de 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();
}
}
Listagem de uma política de 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();
}
}
Tenha uma política de 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();
}
}
Excluir uma política de 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();
}
}
Criação de um cofre de 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();
}
}
Listagem de cofres de 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();
}
}
Obter cofres de 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();
}
}
Atualizar cofres de 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();
}
}
Excluir um cofre de 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();
}
}
Faixas de recuperação de listagem
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();
}
}
Obter faixa de recuperação
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();
}
}
Atualizar faixa de recuperação
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();
}
}
Iniciando uma restauração
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();
}
}
Restauração de listagem
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();
}
}
Obter detalhes da restauração
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();
}
}
Crie um novo bucket COS com bloqueio de objeto ativado
public static void createBucket(String bucketName, AmazonS3 _cosClient)
{
_cosClient.createBucket(bucketName);
System.out.printf("Bucket: %s created!\n", bucketName);
}
Configure o bloqueio de objetos com o modo de conformidade no bucket Object Storage
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);
}
Configurar o bloqueio de objetos com o modo de governança no bucket Object Storage
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);
}
Obter a configuração do bloqueio de objetos no bucket Object Storage
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);
}
Carregar um objeto com o modo de governança no bucket Object Storage
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);
}
Ative a retenção de bloqueio de objeto com o modo de conformidade no objeto
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);
}
Ative a retenção de bloqueio de objeto com o modo de governança no objeto
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);
}
Obter retenção de bloqueio de objeto
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);
}
Colocar objeto em bloqueio legal
public static void putObjectLockLegalHold(String bucketName,string itemName, AmazonS3 _cosClient)
{
ObjectLockLegalHold objLegalHold = new ObjectLockLegalHold()
.withStatus("ON");
SetObjectLegalHoldRequest objSetLegalHold = new SetObjectLegalHoldRequest()
.withBucketName(bucketName)
.withKey(itemName)
.withLegalHold(objLegalHold);
_cosClient.setObjectLegalHold(objSetLegalHold);
System.out.printf("Successfully added object lock legal hold on : %s\n", itemName);
GetObjectLegalHoldRequest objReqLegal = new GetObjectLegalHoldRequest()
.withBucketName(bucketName)
.withKey(itemName);
GetObjectLegalHoldResult objResLegal = _cosClient.getObjectLegalHold(objReqLegal);
System.out.printf("ObjectLock Legal Hold : %s\n", objResLegal.getLegalHold());
}
Obter bloqueio de objeto legalhold
public static void getObjectLockLegalHold(String bucketName,string itemName, AmazonS3 _cosClient)
{
GetObjectLegalHoldRequest objReqLegal = new GetObjectLegalHoldRequest()
.withBucketName(bucketName)
.withKey(itemName);
GetObjectLegalHoldResult objResLegal = _cosClient.getObjectLegalHold(objReqLegal);
System.out.printf("ObjectLock Legal Hold : %s\n", objResLegal.getLegalHold());
}
Excluindo um objeto com o modo de governança de bloqueio de objetos usando a governança de 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);
}
Fazer upload de objetos maiores usando um Transfer Manager
O TransferManager simplifica as grandes transferências de arquivos, incorporando automaticamente uploads de múltiplas partes sempre que necessário ao configurar parâmetros de configuração.
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();
}
Referências do SDK.
Classes
Métodos
Usando o Key Protect
O Key Protect pode ser incluído em um depósito de armazenamento para criptografar dados sensíveis em repouso na nuvem.
Antes de iniciar
Os itens a seguir são necessários para criar um bucket com o Key-Protect ativado:
- Um serviço Key Protect provisionado
- Uma chave Raiz disponível (gerada ou importada)
Recuperando o CRN da chave raiz
- Recupere o ID da instância para seu serviço Key Protect
- Use a API do Key Protect para recuperar todas as suas chaves disponíveis
- É possível usar comandos
curlou um Cliente REST de API, como Postman, para acessar a API do Key Protect.
- É possível usar comandos
- Recupere o CRN da chave raiz que você usa para habilitar o Key Protect no seu bucket. O CRN se parece com o exemplo a seguir:
crn:v1:bluemix:public:kms:us-south:a/3d624cd74a0dea86ed8efe3101341742:90b6a1db-0fe1-4fe9-b91e-962c327df531:key:0bg3e33e-a866-50f2-b715-5cba2bc93234
Criando um depósito com o Key-Protect ativado
private static String COS_KP_ALGORITHM = "<algorithm>";
private static String COS_KP_ROOTKEY_CRN = "<root-key-crn>";
public static void createBucketKP(String bucketName) {
System.out.printf("Creating new encrypted bucket: %s\n", bucketName);
EncryptionType encType = new EncryptionType();
encType.setKmsEncryptionAlgorithm(COS_KP_ALGORITHM);
encType.setIBMSSEKMSCustomerRootKeyCrn(COS_KP_ROOTKEY_CRN);
CreateBucketRequest req = new CreateBucketRequest(bucketName).withEncryptionType(encType);
_cos.createBucket(req);
System.out.printf("Bucket: %s created!", bucketName);
}
Valores da chave
<algorithm>- O algoritmo de criptografia utilizado para novos objetos adicionados ao bucket (o padrão é o AES256 ).<root-key-crn>- CRN da chave raiz obtida do serviço Key Protect.
Referências do SDK.
Classes
Métodos
Novos cabeçalhos para o Key Protect
Os cabeçalhos adicionais foram definidos na 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";
A mesma seção da implementação de criação de bucket que já adiciona cabeçalhos de instância de serviço do IAM também adiciona os dois novos cabeçalhos de criptografia:
//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());
}
}
Os HeadBucketResult objetos ObjectListing e foram atualizados para incluir IBMSSEKPCustomerRootKeyCrn variáveis booleanas e IBMSSEKPEnabled String com métodos getter e setter. Eles armazenam
os valores dos novos cabeçalhos.
GET depósito
public ObjectListing listObjects(String bucketName)
public ObjectListing listObjects(String bucketName, String prefix)
public ObjectListing listObjects(ListObjectsRequest listObjectsRequest)
A classe ObjectListing requer 2 métodos adicionais:
ObjectListing listing = s3client.listObjects(listObjectsRequest)
String KPEnabled = listing.getIBMSSEKPEnabled();
String crkId = listing.getIBMSSEKPCrkId();
Os cabeçalhos adicionais foram definidos dentro da 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";
O S3XmlResponseHandler que é responsável por desserializar todas as respostas xml. Foi adicionada uma verificação para garantir que o resultado seja uma instância de ObjectListing e que os cabeçalhos recuperados sejam adicionados
ao objeto ObjectListing:
if (result instanceof ObjectListing) {
if (!StringUtils.isNullOrEmpty(responseHeaders.get(Headers.IBM_SSE_KP_ENABLED)){
((ObjectListing) result).setIBMSSEKPEnabled(Boolean.parseBoolean(responseHeaders.get(Headers.IBM_SSE_KP_ENABLED)));
}
if (!StringUtils.isNullOrEmpty(responseHeaders.get(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN))) {
((ObjectListing) result).setIBMSSEKPCrk(responseHeaders.get(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN));
}
}
HEAD depósito
Os cabeçalhos adicionais foram definidos na 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";
Estas variáveis são preenchidas no 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();
Usando o Aspera High-Speed Transfer
Ao instalar a biblioteca de transferência de alta velocidade da Aspera, você poderá realizar transferências de arquivos em alta velocidade dentro do seu aplicativo. A biblioteca Aspera é de código fechado e, portanto, uma dependência opcional para o SDK Object Storage (que utiliza uma licença Apache ).
Cada sessão do Aspera high-speed transfer gera um processo ascp individual que é executado na máquina do cliente para executar a transferência. Assegure-se de que seu ambiente de computação possa permitir que esse processo seja
executado.
Você precisa de instâncias das classes Cliente S3 e Gerenciador de tokens do IAM para inicializar o AsperaTransferManager. O s3Client é necessário para obter as informações de conexão do FASP para o bucket de destino
Object Storage. O tokenManager é necessário para permitir que o SDK de transferência em alta velocidade da Aspera se autentique no bucket de destino Object Storage.
Inicializando o AsperaTransferManager
Antes de inicializar o AsperaTransferManager, certifique-se de que você tenha trabalhado com objetos s3Client e tokenManager.
É recomendável usar TokenManager tokenManager = new DefaultTokenManager(new DelegateTokenProvider(apiKey)); e evitar .withTokenManager(tokenManager) ao construir AsperaTransferManager com AsperaTransferManagerBuilder.
Não há muito benefício em usar uma única sessão do Aspera high-speed transfer, a menos que você espere ver um ruído significativo ou perda de pacote na rede. Portanto, é necessário informar ao AsperaTransferManager para usar múltiplas
sessões usando a classe AsperaConfig. Isso divide a transferência em várias sessões paralelas que enviam blocos de dados cujo tamanho é definido pelo valor limite.
A configuração típica para usar múltiplas sessões deve ser:
- Taxa de destino de 2500 MBps
- Limite de 100 MB (esse é o valor recomendado para a maioria dos aplicativos)
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();
No exemplo acima, o sdk gera sessões suficientes para tentar atingir a taxa de destino de 2500 MBps.
Como alternativa, o gerenciamento de sessões pode ser configurado explicitamente no sdk. Isso é útil em casos em que o controle mais preciso sobre a utilização de rede é desejado.
A configuração típica para usar múltiplas sessões explícitas deve ser:
- 2 ou 10 sessões
- Limite de 100 MB (esse é o valor recomendado para a maioria dos aplicativos)
AsperaConfig asperaConfig = new AsperaConfig()
.withMultiSession(2)
.withMultiSessionThresholdMb(100);
TokenManager tokenManager = new DefaultTokenManager(new DelegateTokenProvider(API_KEY));
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(API_KEY, s3Client)
.withAsperaConfig(asperaConfig)
.build();
Para obter o melhor desempenho na maioria dos cenários, utilize sempre várias sessões para minimizar qualquer processamento associado à instância de uma transferência de alta velocidade da Aspera. Se sua capacidade de rede for pelo menos 1 Gbps, será necessário usar 10 sessões. As redes de largura da banda inferior devem usar duas sessões.
Valores da chave
API_KEY- uma chave de API para um ID de usuário ou de serviço com funções de Gravador ou Gerenciador
É necessário fornecer uma chave de API do IAM para criar um AsperaTransferManager. Credenciais de HMAC NÃO são suportadas atualmente Para obter mais informações sobre o IAM, clique aqui.
Upload de arquivo
String filePath = "<absolute-path-to-source-data>";
String bucketName = "<bucket-name>";
String itemName = "<item-name>";
// Load file
File inputFile = new File(filePath);
// Create AsperaTransferManager for FASP upload
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(API_KEY, s3Client).build();
// Upload test file and report progress
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.upload(bucketName, itemName, inputFile);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
Valores da chave
<bucket-name>- nome do bucket na sua instância do serviço Object Storage que tem o Aspera habilitado.<absolute-path-to-source-data>- nome do diretório e do arquivo a ser enviado para o Object Storage.<item-name>- nome do novo objeto adicionado ao bucket.
Download de arquivo
String bucketName = "<bucket-name>";
String outputPath = "<absolute-path-to-file>";
String itemName = "<item-name>";
// Create local file
File outputFile = new File(outputPath);
outputFile.createNewFile();
// Create AsperaTransferManager for FASP download
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(COS_API_KEY_ID, s3Client)
.withTokenManager(tokenManager)
.withAsperaConfig(asperaConfig)
.build();
// Download file
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.download(bucketName, itemName, outputPath);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
Valores da chave
<bucket-name>- nome do bucket na sua instância do serviço Object Storage que tem o Aspera habilitado.<absolute-path-to-file>- nome do diretório e do arquivo a ser salvo no Object Storage.<item-name>- nome do objeto no bucket.
Upload de diretório
String bucketName = "<bucket-name>";
String directoryPath = "<absolute-path-to-directory-for-new-file>";
String directoryPrefix = "<virtual-directory-prefix>";
boolean includeSubDirectories = true;
// Load Directory
File inputDirectory = new File(directoryPath);
// Create AsperaTransferManager for FASP upload
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(COS_API_KEY_ID, s3Client)
.withTokenManager(tokenManager)
.withAsperaConfig(asperaConfig)
.build();
// Upload test directory
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.uploadDirectory(bucketName, directoryPrefix, inputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
Valores da chave
<bucket-name>- nome do bucket na sua instância do serviço Object Storage que tem o Aspera habilitado.<absolute-path-to-directory>- diretório dos arquivos a serem enviados para o Object Storage.<virtual-directory-prefix>- nome do prefixo do diretório a ser adicionado a cada arquivo no momento do upload. Use a sequência nula ou vazia para fazer upload dos arquivos para a raiz do depósito.
Download de diretório
String bucketName = "<bucket-name>";
String directoryPath = "<absolute-path-to-directory>";
String directoryPrefix = "<virtual-directory-prefix>";
boolean includeSubDirectories = true;
// Load Directory
File outputDirectory = new File(directoryPath);
// Create AsperaTransferManager for FASP download
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(COS_API_KEY_ID, s3Client)
.withTokenManager(tokenManager)
.withAsperaConfig(asperaConfig)
.build();
// Download test directory
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
Valores da chave
<bucket-name>- nome do bucket na sua instância do serviço Object Storage que tem o Aspera habilitado.<absolute-path-to-directory>- diretório para salvar arquivos baixados do Object Storage.<virtual-directory-prefix>- nome do prefixo do diretório de cada arquivo a ser baixado. Use uma sequência nula ou vazia para fazer download de todos os arquivos no depósito.
Substituindo a configuração de sessão em uma Base por transferência
É possível substituir os valores de configuração de múltiplas sessões em uma base por transferência passando uma instância de AsperaConfig para os métodos de upload e download sobrecarregados. Usando AsperaConfig,
é possível especificar o número de sessões e o tamanho mínimo do limite de arquivo por sessão.
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();
Monitorando o progresso de transferência
A maneira mais simples de monitorar o progresso de suas transferências de arquivo/diretório é usar a propriedade isDone() que retorna true quando sua transferência é concluída.
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);
}
Você também pode verificar se uma transferência está na fila para processamento chamando o método onQueue no AsperaTransaction. onQueue retorna um valor booleano, em que true indica que a
transferência está na fila.
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
while (!asperaTransaction.isDone()) {
System.out.println("Directory download is in queueing: " + asperaTransaction.onQueue());
//pause for 3 seconds
Thread.sleep(1000 * 3);
}
Para verificar se uma transferência está em andamento, chame o método de progresso em 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);
}
Por padrão, toda transferência tem um anexado TransferProgress a ela. O relata TransferProgress o número de bytes transferidos e a porcentagem transferida do total de bytes a serem transferidos. Para acessar o TransferProgress de uma transferência, use o método getProgress em AsperaTransaction.
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
while (!asperaTransaction.isDone()) {
TransferProgress transferProgress = asperaTransaction.getProgress();
//pause for 3 seconds
Thread.sleep(1000 * 3);
}
Para relatar o número de bytes transferidos, chame o método getBytesTransferred em TransferProgress. Para relatar a porcentagem transferida do total de bytes a serem transferidos, chame o método getPercentTransferred em 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);
}
Pausar/Continuar/Cancelar
O SDK fornece a capacidade de gerenciar o progresso de transferências de arquivos/diretórios por meio dos métodos a seguir do objeto AsperaTransfer:
pause()resume()cancel()
Não há efeitos colaterais ao chamar um dos métodos descritos acima. A limpeza e a manutenção adequadas são manipuladas pelo SDK.
O exemplo a seguir mostra um possível uso para esses métodos:
String bucketName = "<bucket-name>";
String directoryPath = "<absolute-path-to-directory>";
String directoryPrefix = "<virtual-directory-prefix>";
boolean includeSubDirectories = true;
AsperaTransferManager asperaTransferMgr = new AsperaTransferManagerBuilder(COS_API_KEY_ID, _cos)
.withTokenManager(TOKEN_MANAGER)
.build();
File outputDirectory = new File(directoryName);
System.out.println("Starting directory download...");
//download the directory from cloud storage
Future<AsperaTransaction> asperaTransactionFuture = asperaTransferMgr.downloadDirectory(bucketName, directoryPrefix, outputDirectory, includeSubDirectories);
AsperaTransaction asperaTransaction = asperaTransactionFuture.get();
int pauseCount = 0;
while (!asperaTransaction.isDone()) {
System.out.println("Directory download in progress...");
//pause the transfer
asperaTransfer.pause();
//resume the transfer
asperaTransfer.resume();
//cancel the transfer
asperaTransfer.cancel();
}
System.out.println("Directory download complete!");
Resolução de problemas do Aspera
Problema: os desenvolvedores que usam o Oracle JDK no Linux ou Mac OS X podem sofrer travamentos inesperados e silenciosos durante as transferências
Causa: o código nativo requer seus próprios manipuladores de sinal que podem estar substituindo os manipuladores de sinal da JVM. Pode ser necessário usar o recurso de encadeamento de sinal da JVM.
Os usuários do IBM® JDK ou do Microsoft® Windows não são afetados.
Solução: vincule e carregue a biblioteca de encadeamento de sinal da JVM.
-
No Linux, localize a biblioteca compartilhada
libjsig.soe configure a variável de ambiente a seguir:LD_PRELOAD=<PATH_TO_SHARED_LIB>/libjsig.so
-
No Mac OS X, localize a biblioteca compartilhada
libjsig.dylibe configure as variáveis de ambiente a seguir:DYLD_INSERT_LIBRARIES=<PATH_TO_SHARED_LIB>/libjsig.dylibDYLD_FORCE_FLAT_NAMESPACE=0
Acesse a documentação do JDK da Oracle® para obter mais informações sobre encadeamento de sinais.
Problema: UnsatisfiedLinkError no Linux
Causa: o sistema não é capaz de carregar bibliotecas dependentes. Erros como os a seguir podem ser vistos nos logs do aplicativo:
libfaspmanager2.so: libawt.so: cannot open shared object file: No such file or directory
Solução: configure a variável de ambiente a seguir:
LD_LIBRARY_PATH=<JAVA_HOME>/jre/lib/amd64/server:<JAVA_HOME>/jre/lib/amd64
Atualizando os metadados
Há duas maneiras de atualizar os metadados em um objeto existente:
- Uma solicitação
PUTcom os novos metadados e o conteúdo do objeto original - Executando uma solicitação
COPYcom os novos metadados especificando o objeto original como a origem de cópia
Usando PUT para atualizar metadados
A solicitação PUT sobrescreve o conteúdo existente do objeto; portanto, ele deve primeiro ser baixado e reenviado com os novos metadados.
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);
}
Usando COPY para atualizar metadados
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);
}
Usando o Immutable Object Storage
Incluir uma configuração de proteção em um depósito existente
Essa implementação da operação PUT usa o parâmetro de consulta protection para configurar os parâmetros de retenção para um depósito existente. Essa operação permite configurar ou mudar os períodos mínimo, padrão
e máximo de retenção. Essa operação também permite mudar o estado de proteção do depósito.
Os objetos gravados em um depósito protegido não podem ser excluídos até que o período de proteção tenha expirado e todas as retenções legais no objeto sejam removidas. O valor de retenção padrão do depósito é fornecido para um objeto, a menos que um valor específico do objeto seja fornecido quando o objeto for criado. Os objetos em buckets protegidos que não estão mais sob retenção (o período de retenção expirou e o objeto não está sujeito a nenhuma retenção legal), quando sobrescritos, voltam a ficar sob retenção. O novo período de retenção pode ser fornecido como parte da solicitação de sobrescrita do objeto, ou o tempo de retenção padrão do bucket é aplicado ao objeto.
Os valores mínimo e máximo suportados para as configurações do período de retenção MinimumRetention, DefaultRetention, e MaximumRetention são, no mínimo, 0 dias e, no máximo, 365.243 dias (1.000 anos).
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);
}
Verificar a proteção em um depósito
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());
}
}
Fazer upload de um objeto protegido
Os objetos em buckets protegidos que não estão mais sob retenção (o período de retenção expirou e o objeto não está sujeito a nenhuma retenção legal), quando sobrescritos, voltam a ficar sob retenção. O novo período de retenção pode ser fornecido como parte da solicitação de sobrescrita do objeto, ou o tempo de retenção padrão do bucket é aplicado ao objeto.
| Valor | Tipo | Descrição |
|---|---|---|
Retention-Period |
Número inteiro não negativo (segundos) | O período de retenção para armazenar o objeto em segundos. O objeto não pode ser sobrescrito nem excluído até que a quantia de tempo especificada no período de retenção tenha decorrido. Se esse campo e Retention-Expiration-Date forem especificados, um erro 400 será retornado. Se nenhuma das opções for especificada, será utilizado o período DefaultRetention do bucket. Zero (0) é um valor legal que supõe que o período
mínimo de retenção do depósito também é 0. |
Retention-expiration-date |
Data (formato ISO 8601) | A data em que é legal excluir ou modificar o objeto. É possível especificar somente isso ou o cabeçalho Retention-Period. Se ambos forem especificados, é retornado um erro 400. Se nenhuma das opções for especificada, será
utilizado o período de retenção padrão ( DefaultRetention ) do bucket. |
Retention-legal-hold-id |
string | Uma única retenção legal para aplicar ao objeto. Uma retenção legal é uma sequência longa de caracteres Y. O objeto não pode ser sobrescrito nem excluído até que todas as retenções legais associadas ao objeto sejam removidas. |
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);
}
Incluir ou remover uma retenção legal para ou de um objeto protegido
O objeto pode suportar 100 retenções legais:
- Um identificador de retenção legal é uma sequência de comprimento máximo de 64 caracteres e um comprimento mínimo de 1 caractere. Os caracteres válidos são letras, números,
!,_,.,*,(,), e-'. - Se a adição da retenção legal em questão fizer com que o total de retenções legais no objeto ultrapasse 100, a nova retenção legal não será adicionada e um erro
400será retornado. - Se um identificador for muito longo, ele não será adicionado ao objeto, e um erro
400será retornado. - Se um identificador contiver caracteres inválidos, ele não será adicionado ao objeto e um erro
400será retornado. - Se um identificador já estiver em uso em um objeto, a retenção legal existente não será modificada e a resposta indicará que o identificador já estava em uso com um erro
409. - Se um objeto não tiver metadados de período de retenção, um erro
400será retornado e a inclusão ou remoção de uma retenção legal não será permitida.
A presença de um cabeçalho de período de retenção é necessária, caso contrário, um erro 400 é retornado.
O usuário que faz a inclusão ou remoção de uma retenção legal deve ter as permissões Manager para esse depósito.
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);
}
Ampliar o período de retenção de um objeto protegido
O período de retenção de um objeto pode somente ser ampliado. Ele não pode ser diminuído do valor configurado atualmente.
O valor de expansão de retenção é configurado de uma de três maneiras:
- tempo adicional do valor atual (
Additional-Retention-Periodou método semelhante) - novo período de extensão em segundos (
Extend-Retention-From-Current-Timeou método semelhante) - nova data de validade de retenção do objeto (
New-Retention-Expiration-Dateou método semelhante)
O período de retenção atual armazenado nos metadados do objeto é aumentado pelo tempo adicional fornecido ou substituído pelo novo valor, dependendo do parâmetro que está configurado na solicitação extendRetention. Em todos os
casos, o parâmetro de ampliação de retenção é verificado com relação ao período de retenção atual e o parâmetro ampliado será aceito somente se o período de retenção atualizado for maior que o período de retenção atual.
Os objetos em buckets protegidos que não estão mais sob retenção (o período de retenção expirou e o objeto não está sujeito a nenhuma retenção legal), quando sobrescritos, voltam a ficar sob retenção. O novo período de retenção pode ser fornecido como parte da solicitação de sobrescrita do objeto, ou o tempo de retenção padrão do bucket é aplicado ao objeto.
public static void extendRetentionPeriodOnObject(String bucketName, String objectName, Long additionalSeconds) {
System.out.printf("Extend the retention period on %s in bucket %s by %s seconds.\n", objectName, bucketName, additionalSeconds);
ExtendObjectRetentionRequest req = new ExtendObjectRetentionRequest(
bucketName,
objectName)
.withAdditionalRetentionPeriod(additionalSeconds);
cos.extendObjectRetention(req);
System.out.printf("New retention period on %s is %s\n", objectName, additionalSeconds);
}
Listar retenções legais em um objeto protegido
Essa operação retorna:
- Data de criação do objeto
- Período de retenção do objeto em segundos
- Data de expiração de retenção calculada com base no período e data de criação
- Lista de retenções legais
- Identificador de retenção legal
- Registro de data e hora em que a retenção legal foi aplicada
Se não houver retenções legais no objeto, um LegalHoldSet vazio será retornado. Se não houver nenhum período de retenção especificado no objeto, um erro 404 será retornado.
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);
}
}
Criar um website estático hospedado
Esta operação requer que uma instrução de importação seja incluída:
import com.ibm.cloud.objectstorage.services.s3.model.model.BucketWebsiteConfiguration;
Esta operação fornece o seguinte na configuração e requer um cliente configurado corretamente:
- Configuração do depósito para sufixo (documento de índice)
- Configuração do depósito para chave (documento de erro)
cosClient.setBucketWebsiteConfiguration("<bucket_name>", new BucketWebsiteConfiguration("index.html", "error.html"));
Próximas etapas
Para obter mais informações, consulte o Javadoc O código-fonte para o projeto pode ser localizado no GitHub repositório.