2012年8月2日木曜日

GAE/GでGoogle Cloud Storageを利用するには(1)

いろいろ都合があって、GAE/Gから、Google Cloud Storageを利用してみたので
利用方法をメモしておきます。
GAE/GのFileServiceはなぜか、ドキュメントに記載されていない(8/2現在)ので、
GAE/GのSDKのソースコードを見て使い方を理解する必要があります。
(もしくは、Python版、Java版のプログラムから推測するとか…)
ということで、時間がある時にいじって、Blogにメモしようと思います。

1. Google API Consoleで課金設定をONにする。

Google Cloud Storageは課金設定をONにしないと、書き込みも読み込みも、Bucketの作成さえもできないようなので、課金をONにします。

課金をONにしないとIO_ERRORになってしまいます。

※ローカル環境では、何もしなくても実行可能なので、ローカルでしか動かさないという人は、この手順は不要です。

2. Google APIs ConsoleのTeamにサービスのアカウントを追加する。

GAEのアプリケーションからアクセスさせるためには、API Consoleにサービスのアカウントを追加しなければPERMISSION_DENIEDでエラーになります。

サービスのアカウントの場所は、http://appengine.google.comのGAEのアプリケーションにある、
Application→Application Settingsを開きBasic(一番上)のService Account Nameにあるので、書かれているアカウントをコピーします。

[app-id]@appspot.gserviceaccount.com

みたいなものが、書かれていると思います。
(app-idは作成したappidが書かれています。)

Google APIs ConsoleのTeamのところに、ペーストして、権限設定をして追加すれば完了です。


※ローカル環境では、何もしなくても実行可能なので、ローカルでしか動かさないという人は、この手順は不要です。


3. Go言語でプログラムを作成し、デプロイする。

package controller

import (
 "appengine"
 "appengine/file"
 "fmt"
 "net/http"
)

func init() {
 http.HandleFunc("/", list)
}

func list(w http.ResponseWriter, r *http.Request) {
 c := appengine.NewContext(r)

 name, err := file.DefaultBucketName(c); 
 if err != nil {
  http.Error(w, err.Error(), http.StatusInternalServerError)
 } else {
  fmt.Fprintf(w, "DefaultBucketName = %s", name)
 }

 options := new(file.CreateOptions)
 options.MIMEType = "text/plain"
 options.BucketName = "yourBucketName"

// if wc, absFileName, cErr := file.Create(c, "/gs/yourBucketName/test/sample.txt", options); cErr != nil {
 if wc, absFileName, cErr := file.Create(c, "test/sample.txt", options); cErr != nil {
  fmt.Fprintf(w, "Create Error")
  fmt.Fprintf(w, " %s", absFileName)
  c.Debugf("Create Error %s [%s]", cErr.Error(), absFileName)
 } else {
  fmt.Fprintf(w, "Create Success")
  fmt.Fprintf(w, " %s", absFileName)

  if _, wErr := wc.Write([]byte("Sample Text")); wErr != nil {
   c.Debugf("Write Error = %s", wErr.Error())
  }

  wc.Close()

  if fi, statErr := file.Stat(c, absFileName); statErr != nil {
   c.Debugf("%s", statErr.Error())
  } else {
   c.Debugf("%s %d", fi.Name(), fi.Size())
  }
 }

}

4. 実行

上記のプログラムを実行すると、作成したBucketの中のtestフォルダの中にsample.txtが
作成されていると思います。

GAE/Gだと、file.CreateOptionsにBucketNameが指定されていないと、デフォルトの
BucketNameが設定される様になっているのですが、本番環境では、""(空文字列)なので
作成時にエラーになると思います。(BucketNameは必ず指定する必要があるので)
(ちなみに、ローカル環境だと"app_default_bucket"というのが設定されます)

後は、プログラムを見れば大体わかると思いますが、ファイル作成時は、絶対パス指定でも、
相対パス指定でもファイルの参照は可能です。

絶対パス指定の場合は、先頭に"/gs"をつける必要があります。
書式は「/gs/[Bucket名]/フォルダ名/ファイル名」となります。
フォルダ名を省略すれば、Bucketの直下(という表現が正しいのか?)に作成されると思います。

ということで、課金が恐ろしいですが、
1GBあたり、$0.12とか、$0.01とか、ある程度のところまでは、円高のおかげでうまい棒程度で済みそうなので
いろいろいじってみたいと思います。
(参考:https://developers.google.com/storage/docs/pricingandterms?hl=ja