AWS SDK for Javaを使う#S3

2012.02.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

いまやクラウドサービスの代表格とも言えるAmazonですが、EC2やS3をはじめとして、さまざまなサービスを提供しています。数年前に私も少しだけEC2やS3を使用したことがあるのですが、最近はあまりさわっていませんでした。 しかし今回AWSについての調査をきっかけに、各種AWSサービスについて復習&AWS SDKでの動作確認をしていきたいと思います。

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.7.2
  • Java : 1.6.0_26
  • Scala : 2.9.1 final
  • SBT : 0.11.2

なお、AWSへの登録は終わっているものとします。

Amazon S3

Amazon S3 (Amazon Simple Storage Service) とは、オンラインストレージのWebサービスです。 これもEC2と同様、ポピュラーなAWSサービスですね。 ストレージ容量無制限、利用量と転送量から料金が決まる従量課金、REST APIで操作可能という特徴を持っています。 主な特徴は以下のとおりです。(公式ドキュメントから引用)

  • 1バイトから5テラバイトまでのデータを含むオブジェクトを書き込み、読み込み、削除可能
  • 各オブジェクトはバケット内に格納され、開発者が設定した独自のキーを使用する
  • バケットの格納先は複数あるリージョンから選択可能
  • 格納中の安全なデータのアップロード/ダウンロードやデータ暗号化のオプションがある

ドキュメントを見ていて、以前にはなかった「低冗長化ストレージ(Reduced Redundancy Storage、RRS)」というものを発見。 これはAmazon S3のストレージオプションで、標準ストレージよりも低レベルの冗長性で格納することにより、通常の3割くらい安くできるようです。(それでも通常のディスクよりはるかに堅牢性は高い) では今回はRRSをつかってAPIからS3にアクセスしてみましょう。

実行環境のセットアップ

今回はS3に対してバケットの作成やオブジェクトのアップロードをプログラムから実行してみます。 以前と同じくsbt + scala + aws-sdk-javaをセットアップしておきましょう。

今回アップロードするサンプルのsample.txtをawsディレクトリ(プロジェクトディレクトリ)直下に作成します。 そしてsrc/main/scalaディレクトリに、今回使用するクラス、S3.scalaを作成しましょう。 以前作成したsbtプロジェクトに追加した場合、どちらも実行可能クラスなので、実行時にどのクラスを実行するか聞かれます。

S3サンプル作成

サンプルの全文です。今回はバケットの作成からオブジェクトのputし、オブジェクト情報を取得、最後にバケットとオブジェクトを削除しています。

import com.amazonaws._
import com.amazonaws.auth._
import com.amazonaws.services.s3.AmazonS3
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.model._
import scala.collection.JavaConversions._

import java.util.UUID
import java.io.File

object S3Main extends App {

  //アクセスキー
  val accessKey = "アクセスキー"
  //シークレットキー
  val secretKey = "シークレットキー"

  val credentials = new BasicAWSCredentials(accessKey,secretKey)

  //S3オブジェクト作成
  println("create AmazonS3Client ");
  val s3 = new AmazonS3Client(credentials)
  val bucketName = "samplebucket-" + UUID.randomUUID()
  val key = "MyObjectKey"

  //バケット作成
  println("-----create Bucket ")
  s3.createBucket(bucketName)

  //バケット取得して表示
  println("-----show Buckets ")
  for (bucket <- s3.listBuckets()) {
    println(" - " + bucket.getName())
  }

  //低冗長化ストレージ(Reduced Redundancy Storage/ RRS)でバケットにオブジェクトをput
  println("-----put Object ")
  val obj = new PutObjectRequest(bucketName, key, new File("./sample.txt"))
  obj.setStorageClass(StorageClass.ReducedRedundancy);
  s3.putObject(obj);

  //バケットの中身を取得して表示
  println("-----show Objects ")
  val objectListing = s3.listObjects(new ListObjectsRequest().withBucketName(bucketName))
  for (objectSummary <- objectListing.getObjectSummaries()) {
    println(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")")
  }

  //オブジェクト削除
  println("-----delete Object ")
  s3.deleteObject(bucketName, key)

  //バケットを削除
  println("-----delete Bucket ")
  s3.deleteBucket(bucketName)
}

いくつかポイントを説明します。 S3にアクセスするにはAmazonS3Clientクラスに認証オブジェクトを渡して取得しています。 バケット名は全世界でユニークな必要があるのでUUIDを取得してバケット名を決定。

  //S3オブジェクト作成
  println("create AmazonS3Client ");
  val s3 = new AmazonS3Client(credentials)
  val bucketName = "samplebucket-" + UUID.randomUUID()
  val key = "MyObjectKey"

オブジェクトのputは、なにも指定しなければ通常のストレージに格納されます。 今回はRRSでオブジェクトをputするので、PutObjectRequestにヘッダー情報を追加します。 (PutObjectRequest#setStorageClassにStorageClass.ReducedRedundancyを指定)

  //低冗長化ストレージ(Reduced Redundancy Storage/ RRS)でバケットにオブジェクトをput
  println("-----put Object ");
  val obj = new PutObjectRequest(bucketName, key, new File("./sample.txt"))
  obj.setStorageClass(StorageClass.ReducedRedundancy);
  s3.putObject(obj);

では実行してみましょう。runで実行するとどのクラスを実行するか聞かれるので、2を選択します。

$ sbt
> run

Multiple main classes detected, select one to run:

 [1] EC2Main
 [2] S3Main

実行すると、バケットの作成からクリーンアップまで、ひととおり実行され、画面にアクション結果が表示されます。 ※もし途中でエラーが発生し、バケットやオブジェクトが残ってしまったらAWS Management Consoleから削除してください

まとめ

今回はプログラムからS3を使ってみました。S3はアプリケーションでもよく使用するサービスだと思います。 S3はアクセスコントロールやAWS Identity and Access Management (IAM)と組み合わせて使用する 機会も多いので、そのあたりも今後確認したいと思います。

参考サイトなど