Java 사용 V2

Java v2 용 IBM Cloud® Object Storage SDK는 IBM Cloud Object Storage 을 최대한 활용할 수 있는 기능을 제공합니다.

Java v2 용 IBM Cloud Object Storage SDK는 이 가이드의 범위와 지면을 초과하는 많은 기능과 기능을 갖춘 포괄적인 제품입니다. 자세한 클래스 및 메서드 문서는 Java API 참조 문서를 참조하세요. 소스 코드는 GitHub 저장소에서 찾을 수 있습니다.

새로운 기능 v2

Java v2 용 IBM Cloud Object Storage SDK는 AWS SDK v2 아키텍처를 기반으로 구축된 현대화된 버전으로, 상당한 개선이 이루어졌습니다:

  • 불변 빌더: 모든 요청 및 응답 객체는 스레드 안전성 향상을 위해 불변 빌더 패턴을 사용합니다
  • 현대적인 패키지 구조: 깔끔하게 정리된 새로운 네임스페이스 com.ibm.cos.v2.*
  • 향상된 비동기 지원: 비차단 작업을 위한 S3AsyncClient 도입
  • 개선된 스트리밍: 개선된 스트리밍 API: RequestBody 및 ResponseTransformer
  • 자동 IAM 토큰 관리: SDK가 IAM 토큰 새로 고침을 자동으로 처리합니다
  • 유형 안전: 빌더를 통한 컴파일 타임 유형 검사 강화
  • 최신 HTTP 스택: 비동기 작업을 위한 Apache HTTP 클라이언트 및 Netty 지원

v1 에서 마이그레이션하는 개발자의 경우 마이그레이션 가이드를 참조하세요.

SDK 가져오기

IBM Cloud Object Storage Java SDK v2 를 사용하는 가장 쉬운 방법은 Maven을 사용하여 종속성을 관리하는 것입니다. Maven에 익숙하지 않다면 5분 안에 Maven 시작하기 가이드를 사용하여 시작하고 실행할 수 있습니다.

Maven은 pom.xml이라는 파일을 사용하여 Java 프로젝트에 필요한 라이브러리(및 해당 버전)를 지정합니다. 다음은 IBM Cloud Object Storage Java SDK v2 를 사용하여 Object Storage 에 연결하기 위한 예제 pom.xml 파일입니다.

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

SDK 참조

코어 클래스

신임 정보

구성

스트리밍

예외

클라이언트 작성 및 인증 정보 제공

다음 예에서는 인증 정보(API 키 및 서비스 인스턴스 ID) 제공을 통해 클라이언트 cos가 작성되고 구성됩니다. 이러한 값은 인증 정보 파일 또는 환경 변수로부터 자동으로 가져올 수도 있습니다.

서비스 인증 정보를 생성하고 나면 결과 JSON 문서를 ~/.bluemix/cos_credentials에 저장할 수 있습니다. 이 SDK는 클라이언트 작성 중에 다른 인증 정보가 명시적으로 설정되지 않은 한 이 파일에서 자동으로 인증 정보를 가져옵니다. cos_credentials 파일이 HMAC 키를 포함하는 경우에는 클라이언트가 서명을 사용하여 인증하며, 그렇지 않은 경우에는 제공된 API 키를 사용하여 Bearer 토큰으로 인증합니다.

AWS S3에서 마이그레이션하는 경우에는 다음 형식으로 ~/.aws/credentials에서 인증 정보 데이터를 가져올 수도 있습니다.

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

~/.bluemix/cos_credentials와 ~/.aws/credentials가 모두 있는 경우에는 cos_credentials가 우선권을 갖습니다.

클라이언트 구성에 대한 자세한 내용은 Java API 참조 문서를 참조하세요.

코드 예

몇 가지 기본 기능을 실행하는 완전한 예제 클래스부터 시작하겠습니다. 이 CosExample 클래스는 기존 버킷의 개체를 나열하고, 새 버킷을 만든 다음, 서비스 인스턴스의 모든 버킷을 나열합니다.

필수 정보 수집

  • bucketName 및 newBucketName은 고유하며 DNS를 준수하는 문자열입니다. 버킷 이름은 전체 시스템에서 고유하므로 이 예가 여러 번 실행되는 경우에는 이러한 값을 변경해야 합니다. 삭제 후 10~15분 동안 이름이 예약됩니다.
  • apiKey 는 서비스 자격 증명에 apikey 로 표시된 값입니다.
  • serviceInstanceId 는 서비스 자격 증명에 resource_instance_id 로 표시된 값입니다.
  • endpointUrl 는 https:// 프로토콜을 포함하는 서비스 엔드포인트 URL 입니다. 이는 서비스 자격 증명에 있는 endpoints 값이 아닙니다. 엔드포인트에 대한 자세한 정보는 엔드포인트 및 스토리지 위치를 참조하십시오.
  • location 를 storageClass 의 위치 부분으로 설정해야 합니다. us-south-standard의 경우 이는 us-south가 됩니다. 이 변수는 HMAC 서명의 계산에만 사용되지만, IAM API 키를 사용하는 이 예를 비롯하여 모든 클라이언트에서 필수입니다.
package com.cos;

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

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

public class CosExample {

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

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

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

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

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

        cosClient.close();
    }

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

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

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

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

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

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

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

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

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

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

주요 참고 자료

엔드포인트 판별

엔드포인트에 대한 자세한 정보는 엔드포인트 및 스토리지 위치를 참조하십시오.

엔드포인트는 이 패턴을 따릅니다: https://s3.{region}.cloud-object-storage.appdomain.cloud

예:

  • 미국 남부: https://s3.us-south.cloud-object-storage.appdomain.cloud
  • 미국 동부: https://s3.us-east.cloud-object-storage.appdomain.cloud
  • EU 영국: https://s3.eu-gb.cloud-object-storage.appdomain.cloud

새 버킷 작성

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

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

    cosClient.createBucket(request);

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

키 참조

다른 스토리지 클래스로 버킷 작성

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

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

    cosClient.createBucket(request);

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

스토리지 클래스 옵션에는 다음이 포함됩니다:

  • us-south-standard / us-east-standard / eu-gb-standard- 표준 스토리지
  • us-south-vault / us-east-vault / eu-gb-vault- 볼트 스토리지
  • us-south-cold / us-east-cold / eu-gb-cold- 콜드 볼트 스토리지
  • us-south-flex / us-east-flex / eu-gb-flex- 플렉스 스토리지

키 참조

새 텍스트 파일 작성

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

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

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

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

주요 참고 자료

파일에서 오브젝트 업로드

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

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

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

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

주요 참고 자료

스트림을 사용하여 오브젝트 업로드

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

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

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

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

주요 참고 자료

오브젝트를 파일로 다운로드

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

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

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

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

주요 참고 자료

스트림을 사용하여 오브젝트 다운로드

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

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

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

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

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

주요 참고 자료

오브젝트 복사

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

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

    cosClient.copyObject(request);

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

주요 참고 자료

사용 가능한 버킷 나열

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

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

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

주요 참고 자료

특정 항목의 파일 컨텐츠 가져오기

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

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

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

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

주요 참고 자료

버킷에서 항목 삭제

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

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

    cosClient.deleteObject(request);

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

주요 참고 자료

버킷에서 여러 항목 삭제

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

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

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

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

    DeleteObjectsResponse response = cosClient.deleteObjects(request);

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

주요 참고 자료

버킷 삭제

버킷을 삭제하려면 버킷이 비어 있어야 합니다.

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

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

    cosClient.deleteBucket(request);

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

주요 참고 자료

오브젝트를 공용으로 읽을 수 있는지 확인

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

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

        GetObjectAclResponse response = cosClient.getObjectAcl(request);

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

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

주요 참고 자료

다중 파트 업로드 실행

대형 오브젝트에 대해 작업하는 경우에는 IBM Cloud Object Storage에 오브젝트를 기록할 때 다중 파트 업로드 오퍼레이션을 사용하는 것이 좋습니다. 단일 오브젝트의 업로드는 파트의 세트로 수행할 수 있으며 이러한 파트는 순서에 상관없이 독립적으로 병렬로 업로드할 수 있습니다. 업로드가 완료되면 IBM Cloud Object Storage가 모든 파트를 모아 하나의 오브젝트로 제시합니다.

다중 파트 업로드는 5MB가 넘는 오브젝트에서만 사용 가능합니다. 50GB보다 작은 오브젝트의 경우 최적의 성능을 위해 20MB에서 100MB의 파트 크기가 권장됩니다. 더 큰 오브젝트의 경우에는 성능에 큰 영향을 주지 않고 파트 크기를 늘릴 수 있습니다.

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

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

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

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

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

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

            buffer.flip();

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

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

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

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

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

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

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

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

    cosClient.completeMultipartUpload(completeRequest);

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

주요 참고 자료

불변 오브젝트 스토리지 사용

사용자는 변경 불가 Object Storage 정책으로 버킷을 구성하여 정해진 기간 동안 개체가 수정되거나 삭제되지 않도록 할 수 있습니다. 보존 기간은 개체별로 지정하거나 버킷에 설정된 기본 보존 기간을 개체가 상속받을 수 있습니다.

버킷에 보호 구성 추가하기

이 PUT 오퍼레이션 구현은 protection 조회 매개변수를 사용하여 기존 버킷의 보존 매개변수를 설정합니다. 이 오퍼레이션을 사용하면 최소, 기본 및 최대 보존 기간을 설정하거나 변경할 수 있습니다. 이 오퍼레이션을 사용하면 버킷의 보호 상태를 변경할 수도 있습니다.

보호된 버킷에 작성된 오브젝트는 보호 기간이 만료되어 오브젝트에 대한 모든 법적 보존이 제거될 때까지 삭제할 수 없습니다. 오브젝트가 작성될 때 오브젝트 고유 값이 제공되지 않으면 버킷의 기본 보존 값이 오브젝트에 지정됩니다. 더 이상 보존되지 않는(보존 기간이 만료되어 법적 보존 기간이 없는) 보호된 버킷의 개체는 덮어쓰기를 하면 다시 보존 대상이 됩니다. 새 보존 기간은 오브젝트 겹쳐쓰기 요청의 일부로서 제공될 수 있으며, 그렇지 않은 경우에는 버킷의 기본 보존 기간이 오브젝트에 지정됩니다.

보존 기간 설정 MinimumRetention, DefaultRetention, MaximumRetention 에서 지원되는 최소 및 최대 값은 최소 0일에서 최대 365243일(1000년)입니다.

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

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

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

    cosClient.putBucketProtectionConfiguration(request);

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

버킷의 보호 구성 가져오기

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

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

    GetBucketProtectionConfigurationResponse response = cosClient.getBucketProtectionConfiguration(request);

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

보존이 설정된 보호된 개체 업로드하기

더 이상 보존되지 않는(보존 기간이 만료되어 법적 보존 기간이 없는) 보호된 버킷의 개체는 덮어쓰기를 하면 다시 보존 대상이 됩니다. 새 보존 기간은 오브젝트 겹쳐쓰기 요청의 일부로서 제공될 수 있으며, 그렇지 않은 경우에는 버킷의 기본 보존 기간이 오브젝트에 지정됩니다.

사용자 지정 헤더를 사용하여 보호된 버킷에 개체를 업로드할 때 보존 매개변수를 지정할 수 있습니다:

헤더 유형 설명
Retention-Period 음수가 아닌 정수(초) 오브젝트에 저장할 보존 기간(초)입니다. 오브젝트는 보존 기간에 지정된 시간이 경과하기 전까지 겹쳐쓰거나 삭제할 수 없습니다. 이 필드와 Retention-Expiration-Date 을 지정하면 400 오류가 반환됩니다. 둘 다 지정되지 않은 경우에는 버킷의 DefaultRetention 기간이 사용됩니다. 0(0)은 버킷의 최소 보존 기간도 0이라고 가정한 법적 값입니다.
Retention-Expiration-Date 날짜(ISO 8601 형식) 개체를 삭제하거나 수정할 수 있는 합법적인 날짜입니다. 이 헤더 또는 Retention-Period 헤더만 지정할 수 있습니다. 둘 다 지정하면 400 오류가 반환됩니다. 둘 다 지정되지 않은 경우에는 버킷의 DefaultRetention 기간이 사용됩니다.
Retention-Legal-Hold-Id 문자열 오브젝트에 적용할 단일 법적 보존입니다. 법적 홀드는 Y자로 된 긴 문자열입니다. 오브젝트는 해당 오브젝트와 연관된 모든 법적 보존이 제거될 때까지 겹쳐쓰거나 삭제할 수 없습니다.
public static void uploadProtectedObject(String bucketName, String objectKey, String filePath, S3Client cosClient) {
    System.out.println("Uploading protected object with retention: " + objectKey);

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

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

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

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

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

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

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

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

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

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

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

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

중요 참고사항:

  • 동일한 요청에 Retention-Period 와 Retention-Expiration-Date 을 모두 지정할 수 없습니다.
  • 보존 매개변수를 지정하지 않으면 버킷의 기본 보존 기간이 적용됩니다.
  • 법적 보류는 보존 기간과 결합할 수 있습니다.
  • 보존 중이거나 법적 보존이 설정된 개체는 보존 기간이 만료되고 모든 법적 보존이 제거될 때까지 삭제하거나 덮어쓸 수 없습니다.

주요 참고 자료

보호 대상의 보존 기간 연장하기

오브젝트의 보존 기간은 연장만 가능합니다. 현재 구성된 값에서 줄일 수는 없습니다.

보존 연장 값은 다음 세 가지 방법 중 하나로 설정됩니다.

  • 현재 값에서 추가 시간 (additionalRetentionPeriod 또는 유사한 방법)
  • 새로운 연장 기간(초 단위 ) 설정(extendRetentionFromCurrentTime 또는 유사한 방법)
  • 개체의 새로운 보존 만료일 (newRetentionExpirationDate 또는 유사한 방법)

오브젝트 메타데이터에 저장된 현재 보존 기간은 extendRetention 요청에 설정된 매개변수에 따라 지정된 추가 시간만큼 증가되거나, 새 값으로 대체될 수 있습니다. 모든 경우에 연장 보존 매개변수는 현재 보존 기간과 비교하여 확인되며, 업데이트된 보존 기간이 현재 보존 기간보다 큰 경우에만 연장 매개변수가 허용됩니다.

더 이상 보존되지 않는(보존 기간이 만료되어 법적 보존 기간이 없는) 보호된 버킷의 개체는 덮어쓰기를 하면 다시 보존 대상이 됩니다. 새 보존 기간은 오브젝트 겹쳐쓰기 요청의 일부로서 제공될 수 있으며, 그렇지 않은 경우에는 버킷의 기본 보존 기간이 오브젝트에 지정됩니다.

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

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

    cosClient.extendObjectRetention(request);

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

주요 참고 자료

Key Protect 사용

클라우드의 민감한 저장 데이터를 암호화하기 위해 Key Protect를 스토리지 버킷에 추가할 수 있습니다.

다음을 사용하여 버킷 만들기 Key Protect

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

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

    cosClient.createBucket(request);

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

Key Protect 활성화된 버킷에 개체 업로드하기

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

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

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

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

전송 관리자를 사용한 대형 오브젝트 업로드

전송 관리자는 IBM Cloud Object Storage 에 개체를 업로드하고 다운로드할 수 있는 간단한 API를 제공합니다.

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

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

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

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

        FileUpload upload = transferManager.uploadFile(uploadRequest);

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

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

주요 참고 자료

메타데이터 업데이트

기존 개체의 메타데이터 업데이트하기

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

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

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

    cosClient.copyObject(request);

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

주요 참고 자료

Aspera 고속 전송 사용

Aspera 고속 전송 통합은 IBM Aspera SDK 을 통해 이용할 수 있습니다. IBM Cloud Object Storage 과의 통합에 대한 자세한 내용은 Aspera 문서를 참조하세요.

Java 애플리케이션의 경우, 대용량 파일의 고속 전송을 위해 IBM Cloud Object Storage SDK v2 와 함께 Aspera Transfer SDK 을 사용할 수 있습니다.

개체 잠금 사용

객체 잠금을 사용하면 WORM(Write-once-read-many) 모델을 사용하여 객체를 저장할 수 있습니다. 개체 잠금을 사용하면 일정 시간 또는 무기한 동안 개체가 삭제되거나 덮어쓰이는 것을 방지할 수 있습니다.

개체 잠금이 활성화된 버킷 만들기

버킷 생성 시 Object Lock을 활성화해야 하며 기존 버킷에는 추가할 수 없습니다.

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

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

    cosClient.createBucket(request);

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

객체에서 객체 잠금 유지 설정

개체에 보존을 설정하여 삭제하거나 덮어쓰지 못하도록 할 수 있습니다. 두 가지 보존 모드를 사용할 수 있습니다:

  • 규정 준수: 루트 사용자를 포함한 어떤 사용자도 개체를 덮어쓰거나 삭제할 수 없습니다.
  • 거버넌스: 특별한 권한을 가진 사용자는 보존 설정을 변경하거나 개체를 삭제할 수 있습니다.
public static void putObjectRetention(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Setting object retention for: " + objectKey);

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

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

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

    cosClient.putObjectRetention(request);

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

객체 잠금 유지 정보 가져오기

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

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

    GetObjectRetentionResponse response = cosClient.getObjectRetention(request);

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

객체 잠금 법적 보류 설정

법적 보류는 보존 기간과 동일한 보호 기능을 제공하지만 만료일은 없습니다. 법적 보류는 명시적으로 제거될 때까지 유효합니다.

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

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

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

    cosClient.putObjectLegalHold(request);

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

오브젝트 잠금 법적 보류 상태 가져오기

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

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

    GetObjectLegalHoldResponse response = cosClient.getObjectLegalHold(request);

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

주요 참고 자료

버킷 수명 주기 구성 사용

수명 주기 구성을 통해 IBM Cloud Object Storage 이 개체 그룹에 적용하는 작업을 정의할 수 있습니다. 수명 주기 정책을 사용하여 개체를 다른 스토리지 클래스로 전환하거나 지정된 기간이 지나면 개체를 만료할 수 있습니다.

버킷에서 수명 주기 구성 설정하기

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

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

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

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

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

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

    cosClient.putBucketLifecycleConfiguration(request);

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

버킷의 수명 주기 구성 가져오기

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

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

    GetBucketLifecycleConfigurationResponse response = cosClient.getBucketLifecycleConfiguration(request);

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

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

버킷의 수명 주기 구성 삭제하기

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

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

    cosClient.deleteBucketLifecycle(request);

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

주요 참고 자료

버킷 버전 관리 사용

버전 관리를 사용하면 동일한 버킷에 여러 버전의 개체를 보관할 수 있습니다. 이를 통해 의도하지 않은 사용자 작업 및 애플리케이션 장애로부터 복구하는 데 도움이 될 수 있습니다.

버킷에서 버전 관리 사용 설정하기

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

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

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

    cosClient.putBucketVersioning(request);

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

버킷 버전 관리 상태 가져오기

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

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

    GetBucketVersioningResponse response = cosClient.getBucketVersioning(request);

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

개체 버전 나열

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

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

    ListObjectVersionsResponse response = cosClient.listObjectVersions(request);

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

특정 개체 버전 삭제하기

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

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

    cosClient.deleteObject(request);

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

주요 참고 자료


확장 버킷 리스트 사용

IBM Cloud Object Storage 는 위치 및 스토리지 클래스 정보를 포함하여 버킷에 대한 추가 메타데이터를 반환하는 확장 목록 API를 제공합니다.

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

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

    ListBucketsExtendedResponse response = cosClient.listBucketsExtended(request);

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

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

주요 참고 자료

아카이브 계층 및 개체 복원 사용

IBM Cloud Object Storage 는 저렴한 비용으로 장기간 데이터를 보관할 수 있는 아카이브 스토리지 클래스(Glacier)를 제공합니다. 아카이브 스토리지의 개체는 액세스하기 전에 복원해야 합니다.

개체를 아카이브 스토리지로 전환

수명 주기 정책을 사용하여 지정된 기간이 지나면 자동으로 개체를 아카이브 스토리지로 전환할 수 있습니다.

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

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

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

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

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

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

    cosClient.putBucketLifecycleConfiguration(request);

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

아카이브된 개체 복원하기

아카이브 스토리지에 있는 개체는 다운로드하기 전에 복원해야 합니다. 복원된 사본을 사용할 수 있어야 하는 일수를 지정할 수 있습니다.

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

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

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

    cosClient.restoreObject(request);

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

복원 상태 확인

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

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

    HeadObjectResponse response = cosClient.headObject(request);

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

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

아카이브 검색 가속화

IBM Cloud Object Storage 아카이브 검색 가속화를 지원하여 아카이브된 데이터에 더 빠르게 액세스할 수 있습니다:

  • 신속: 검색 시간 2시간
  • 표준: 3~5시간 검색 시간(기본값)
  • 대량: 5-12시간 검색 시간(최저 비용)
public static void restoreWithExpeditedRetrieval(String bucketName, String objectKey, S3Client cosClient) {
    System.out.println("Restoring with expedited retrieval: " + objectKey);

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

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

    cosClient.restoreObject(request);

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

주요 참고 자료

CORS 사용(출처 간 리소스 공유)

CORS 구성을 사용하면 한 도메인에서 실행되는 웹 애플리케이션이 다른 도메인에서 IBM Cloud Object Storage 의 리소스에 액세스할 수 있습니다.

버킷에 CORS 구성 설정하기

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

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

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

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

    cosClient.putBucketCors(request);

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

CORS 구성 가져오기

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

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

    GetBucketCorsResponse response = cosClient.getBucketCors(request);

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

CORS 구성 삭제

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

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

    cosClient.deleteBucketCors(request);

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

주요 참고 자료


버킷 정책 사용

버킷 정책은 버킷과 개체에 대한 액세스 제어 관리 기능을 제공합니다. JSON으로 작성되며 사용자 및 서비스에 대한 권한을 부여하거나 거부할 수 있습니다.

버킷 정책 설정

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

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

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

    cosClient.putBucketPolicy(request);

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

버킷 정책 가져오기

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

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

    GetBucketPolicyResponse response = cosClient.getBucketPolicy(request);

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

버킷 정책 삭제하기

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

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

    cosClient.deleteBucketPolicy(request);

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

주요 참고 자료


호스팅된 정적 웹사이트 만들기

IBM Cloud Object Storage 버킷에서 직접 정적 웹사이트를 호스팅할 수 있도록 지원합니다. 인덱스 문서와 오류 문서를 지정하여 정적 콘텐츠를 제공하도록 버킷을 구성할 수 있습니다.

이 작업을 수행하려면 다음 가져오기 문이 필요합니다:

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

버킷 웹사이트 구성 설정

이 작업은 구성 시 다음과 같은 기능을 제공하며 올바르게 구성된 클라이언트가 필요합니다:

  • 접미사를 위한 버킷 구성 (색인 문서)
  • 키에 대한 버킷 구성 (오류 문서)
public static void setBucketWebsiteConfiguration(String bucketName, S3Client cosClient) {
    System.out.println("Setting website configuration for bucket: " + bucketName);

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

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

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

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

    cosClient.putBucketWebsite(request);

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

버킷 웹사이트 구성 가져오기

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

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

    GetBucketWebsiteResponse response = cosClient.getBucketWebsite(request);

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

버킷 웹사이트 구성 삭제하기

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

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

    cosClient.deleteBucketWebsite(request);

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

주요 참고 자료

오류 처리 및 모범 사례

SDK 예외 처리하기

v2 SDK는 다양한 오류 시나리오에 대해 특정 예외 유형을 사용합니다.

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

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

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

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

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

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

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

v2 SDK의 모범 사례

  • S3Client 인스턴스를 재사용합니다: 클라이언트를 만드는 데는 비용이 많이 듭니다. 여러 요청에서 재사용하세요.
// Good: Create once, reuse
S3Client client = S3Client.builder()
        .endpointOverride(URI.create(endpoint))
        .credentialsProvider(StaticCredentialsProvider.create(credentials))
        .region(Region.of(region))
        .build();

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

// Close when done
client.close();
  • 리소스를 사용해 보세요: 적절한 리소스 정리를 확인하세요.
try (S3Client client = S3Client.builder()
        .endpointOverride(URI.create(endpoint))
        .credentialsProvider(StaticCredentialsProvider.create(credentials))
        .region(Region.of(region))
        .build()) {

    // Perform operations
    client.listBuckets();

} // Client automatically closed
  • 멀티파트 업로드로 대용량 파일을 처리하세요: 5MB가 넘는 파일의 경우 멀티파트 업로드를 사용하세요.

  • 대용량 전송에는 전송 관리자를 사용하세요: 자동 멀티파트 업로드, 재시도 로직 및 진행 상황 추적 기능을 제공합니다.

  • 적절한 시간 제한을 설정합니다: 사용 사례에 맞게 클라이언트 시간 제한을 구성하세요.

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

주요 참고 자료

추가 자원

도움 받기

이 문서는 IBM Cloud Object Storage Java SDK v2 에 대한 구조와 SDK 참조를 제공합니다. 모든 작업에 대한 완전한 작동 코드 예제는 GitHub 리포지토리의 예제 디렉터리 및 마이그레이션 가이드를 참조하세요.