読者です 読者をやめる 読者になる 読者になる

protocol bufferでmakeSyncCallする get編

あの伝説のMakeSyncCallServletでは、apiproxyを経由して、ローカル環境からgae/jのいろいろなapiをたたくことができます。

MakeSyncCallServletについてはこちら↓
http://shin1o.blogspot.com/2009/10/appengine-makesynccallservlet.html


makesynccallは呼び出しをインターフェイス経由ではなくリフレクション的に文字列で行うことができるので、いろいろ夢が広がります。こっそりインターフェイスにないapiを呼び出したりとか。

以前は、datastoreのschemeを取得するのに失敗しましたが、getは簡単だろうと思ってやってみたらこれも右往左往でした。とりあえずこんな感じです。

// appengineのデータをmakeSyncCallで取得する

// elementを生成する
// elementは文字でエンティティグループを説明しているときのあれっぽいものと思われ
Element element = new Element();

// idを指定する
// data viewerのところで出てくるあのid
// 0以上の数字であればなんでもいいのかも
// とりあえず0渡したらおこられた
element.setId(1);

// nameを指定する
// nameのプロパティはよくわかんない
// id=1001、的な書式でsetidするみたいなのかもだけど試してない
// とりあえずnull渡しておこられた
// element.setName(null);

// typeはkindの名前
// ここはおこられなかった
element.setType(KIND_NAME);

// pathを生成する
// 多分、entity groupをprotocol buffer的に表現したもの
Path path = new Path();
path.addElement(element);

// referenceを生成する
// appidを指定するので、アプリケーション情報とかの環境情報的なものをやり取りするためのものと思われ
Reference reference = new Reference();

// appidを指定しないとおこられる
reference.setApp(APPID);
reference.setPath(path);

// getrequestを生成する
// 行きのpbオブジェクト
// 何をgetするか教えてあげる
GetRequest getRequest = new GetRequest();
getRequest.addKey(reference);

// あの伝説のmakeSyncCallを実行する
byte response[] = ApiProxy.makeSyncCall("datastore_v3", "Get", getRequest.toByteArray());

// getresponceを生成する
// 帰りのpbオブジェクト
GetResponse getResponse = new GetResponse();

// makeSyncCallの戻りのbyte配列をマージする
// なんかC++で配列をどうにかするときみたいな書き方
getResponse.mergeFrom(response);

// ここまでいろいろおこられたけどこんな感じです
System.out.println(getResponse);

実行は、ローカル→MakeSyncCallServletでやりましたが、サーバーにあげるのはやってないです。多分動くと思うけど。

getresponceのsysoutの結果はこんな感じ。

Entity {
entity <
key <
app: "apurikeishonnnonamaegaderuyo"
path <
Element {
type: "Greeting"
id: 1
}
>
>
entity_group <
Element {
type: "Greeting"
id: 1
}
>
property <
name: "content"
value <
stringValue: "test"
>
multiple: false
>
property <
name: "author"
value <

>
multiple: false
>
property <
meaning: 7
name: "date"
value <
int64Value: 0x46a01a6e47058
>
multiple: false
>
>
}

ちなみに、entityを普通にとってきて普通に出力するとこんな感じ。

protocol bufferをsysoutするとentity groupもみれるので、デバッグとかで役に立つかもしれません。


というか、データを取得する程度でこんなにおこられると思わなかった。。


余談ですが、GetSchemaについて(http://d.hatena.ne.jp/marblejenka/20091006/1254853588 で書いてた件)は、appidを指定していなくておこられています。

com.google.apphosting.api.ApiProxy$ApplicationException: ApplicationError: 1: app hogehogehoge cannot access app 's data

"app 's data"は、appidがnullなので"なんとかアプリのデータ"のなんとか部分が消えちゃってた訳です。

request.setApp(appid);

とすると、

ApplicationError: 1: app apurikeishonnnonamaegaderuyo cannot call GetSchema

となるので結局getschemaは呼べないです。残念です。