前回の 「GAE/J用のBigtableのバックアップツールが無い」 で決めた仕様にしたがってバックアップツールを作ってみた。

JSONパーザはWSJSから使い回しなので DataStoreの低レベルAPIを使って読込と書込をするServletを作ってやれば良い。

Servletは dstool とかのバージョンで upload して
dstool.{app-id}.appspot.com にアクセスさせる。

面倒なのはクライアントの方だ。

Download中に30秒ルール等で落ちた場合、 最後の中途半端なEntityの部分を捨てて そこからやり直すリクエストをサーバに送ったりとかしなければいけない。

Uploadも同様に正常に書き込めたEntity数をサーバから返してもらって その続きをできるようにしなけらばならない。

困ったのは現存する Kind の一覧を取る方法が無いこと。 Local環境だと裏技があるみたいだが通常のAPIには無いのか?

もろもろ含めて決めた CUI の仕様。

$ ./bin/dstool.sh Usage: java DsTool <command> [-limit=<n>] [-file=<file>] <url> <kind> <command>: download or upload. download : Download JSON format entities from <url>. upload : Upload JSON format entities to <url>. <url>: DsToolServlet URL. Ex. https://dstool.app-id.appspot.com/dstool <kind>: DataStore kind. Ex. Employee -limit=<n>: The number of the limits of the entity to handle at one request. default=100. -file=<file>: Output or input JSON file. default=stdin/stdout. Eclipse から使う事を考えると GUI も必要だなぁ。

実際にServletを上げて動かしてみた。

$ ./bin/dstool.sh download -file=/tmp/Page.json http://dstool.wsjs-gae.appspot.com/dstool Page Request http://dstool.wsjs-gae.appspot.com/dstool?kind=Page&limit=100 Status: 200 Download 100 entities. Request http://dstool.wsjs-gae.appspot.com/dstool?kind=Page&limit=100&offset=%7B%22name%22%3A%22%2Flib%2Fjscp%2Fimgbtn.pack%22%2C%22type%22%3A%22Key%22%2C%22kind%22%3A%22Page%22%7D Status: 200 Download 98 entities. Request http://dstool.wsjs-gae.appspot.com/dstool?kind=Page&limit=100&offset=%7B%22name%22%3A%22%2Ftmp%2Fmaildata.txt%22%2C%22type%22%3A%22Key%22%2C%22kind%22%3A%22Page%22%7D Status: 204 #Windowsの場合は dstool.bat。

198 entity 取れてる。

落ちて来たデータ。 {__key__:{type:"Key",kind:"Page",name:"/"}, length:0, body:null, parentPageName:null, lastModified:1278830141000, directory:true}, {__key__:{type:"Key",kind:"Page",name:"/_wsjs_"}, length:0, parentPageName:"/", lastModified:1278856948000, directory:true}, {__key__:{type:"Key",kind:"Page",name:"/_wsjs_/develop"}, length:0, parentPageName:"/_wsjs_", lastModified:1286692293086, directory:true}, {__key__:{type:"Key",kind:"Page",name:"/_wsjs_/develop/template"}, length:0, parentPageName:"/_wsjs_/develop", lastModified:1286692306721, directory:true}, {__key__:{type:"Key",kind:"Page",name:"/_wsjs_/develop/template/0.css"}, length:37, body:{type:"Blob",value:"0A2E436C737373207B0A096D617267696E3A20303B0A0970616464696E673A20303B0A7D0A"}, parentPageName:"/_wsjs_/develop/template", lastModified:1286692308802, directory:false}, {__key__:{type:"Key",kind:"Page",name:"/_wsjs_/develop/template/0.exjs"}, length:979, body:{type:"Blob",value:"2F2A2A0A45584A53E381AF4A617661536372697074E38292E4B880E983A8E68BA1E5BCB5E38197E381A6207969656C6420E6A99FE883BDE38292E4BDBFE38188E3828BE38288E38186E381ABE38197E... : : 1Entity=1行で落してくるのでBlobとか有ると凄い事になる。 エディタによっては開けないと思う。 当然、このデータは加工してから upload とかできる。

Downloadしたデータを別のサーバにUploadしてみる。

$ ./bin/dstool.sh upload -file=/tmp/Page.json http://dstool.new-server.appspot.com/dstool Page Status: 200 upload 100 entities. Status: 200 upload 98 entities.

管理画面から確認。ちゃんとuploadできてるみたい。
あ、Keyに親が有った場合、upload順とかを考えないとうまく動かないかも。

基本的な事は出来たけど課題も出て来た。

  • ユーザ認証。
  • GUIクライアント。
  • 削除機能。
  • upload の上書きオプション。
  • download の絞り混み条件。
くらい有ると使い物になりそうな気がする。 認証は OAuth が本命だけどオーバースペックかなぁ。

ここまでのコードは Google code に上がっているので興味のある人は Eclipse の SVN で落してください。