はじめに
「Mojolicious XML-RPC Pluginの開発」のその2です。
本内容では、前回の内容を踏まえ、XML-RPC実装を、Mojoliciousのプラグイン機能を使用して実装しようと思います。
説明は以下の順序で行います。
- Mojolicious XML-RPC Plugin(以下 「FrontierXMLRPC」)とは
- 「FrontierXMLRPC」作成方法
- 「FrontierXMLRPC」使用方法
- 「FrontierXMLRPC」テスト手順
1. Mojolicious XML-RPC Pluginとは
(その1)で行ったXML-RPCの実装を、以下の順序で再実装しようという試みです。
- (1) 「FrontierXMLRPC」を作成する。
- (2) 「FrontierXMLRPC」上でXML-RPC関数を実装する。
「FrontierXMLRPC」プラグインは以下を目標に作成しました。
- 単純にMojoliciousのプラグイン作成お勉強
XML-RPCプラグインなんてどこかにはあると思いますが
軽く調べたところ、目標に合致したものは公開されてないっぽい。 - 簡単設定で関数をexportできる。
- XML入出力を記録できる。記録する処理をコールバックできる。
1.1 「FrontierXMLRPC」概要図
以下に「FrontierXMLRPC」の概念を示します。
XML-RPCクライアント(python) -> Mojolicious雛形 -> 「FrontierXMLRPC」読み込み -> 「FrontierXMLRPC」register関数 -> コールバッククラス
「「FrontierXMLRPC」読み込み」については、「3.「FrontierXMLRPC」使用方法」 にて説明します。
その他は、「2.「FrontierXMLRPC」作成方法」にて説明します。
1.2 本文書でのサンプルについて
サンプルの実装は、[mojoxmlrpcplugin]に置いてあります。
サンプルには以下の内容が入っています。
- 「FrontierXMLRPC」Mojolicious Plugin ソース (以下: FrontierXMLRPC)
- 「FrontierXMLRPC」結合テスト用アプリケーション (FrontierXMLRPC/t/combined/)
2. 「FrontierXMLRPC」作成方法
「FrontierXMLRPC」は以下のように作成しました。
- Mojolicious Plugin 雛形作成
- 「FrontierXMLRPC」register関数作成
- コールバッククラス作成
以下に、個々の作成内容について説明します。
2.1 「FrontierXMLRPC」作成手順詳細
(1) Mojolicious Plugin 雛形作成
最初に、以下のコマンドで、Mojolicious Pluginの雛形を作成します。
$ mojo generate plugin FrontierXMLRPC
Mojolicious Pluginの名前を、「FrontierXMLRPC」としています。
コマンドを起動すると、以下のようなファイルが生成されます。
Mojolicious-Plugin-FrontierXMLRPC/ Makefile.PL lib/ Mojolicious/ Plugin/ FrontierXMLRPC.pm t/ basic.t
主に修正/追加するファイルは、以下の通りです。
- lib/Mojolicious/Plugin/FrontierXMLRPC.pm
- lib/Mojolicious/Plugin/FrontierXMLRPC/RPC2.pm(追加)
- テストコード t/01_load.t,02_xml.t
その他はサンプルに格納されているので、詳細はサンプルを確認してください。
(2)「FrontierXMLRPC」register関数 修正(FrontierXMLRPC.pm)
Mojolicious Pluginの中心は「register」という関数です。雛形のFrontierXMLRPC.pm内、resister関数を以下のように変更します。
package Mojolicious::Plugin::FrontierXMLRPC; use Mojo::Base 'Mojolicious::Plugin'; our $VERSION = '0.01'; use Frontier::RPC2; my $log = Mojo::Log->new; sub register { my ($self, $app, $conf) = @_; #$log->info("FrontierXMLRPC\n"); # XMLRPC my $server = Frontier::RPC2->new( 'encoding' => 'UTF-8' ); if ( !defined $server ) { return ; } # parameter settings $self->{'method'} = $conf->{methods}; $self->{'cb'} = $conf->{cb}; $self->{'rpc2'} = $server; my $r = $app->routes; # prepare "/RPC2" $r->post("/RPC2")->to(namespace => 'Mojolicious::Plugin::FrontierXMLRPC::Rpc2' , action=>'proxy_xmlrpc', frontier_xmlrpc_plugin => $self, ); return ; } 1; __END__
上記で重要なところは、以下の二つです。
- 「FrontierXMLRPC」register関数呼び出し時の情報を
stash->frontier_xmlrpc_plugin
(後述)経由でコンテキスト($self
)に設定する - コントローラクラスの追加(“/RPC2″時)
「FrontierXMLRPC」Mojolicious Pluginがコントローラクラスに値を渡す方法として
stash->frontier_xmlrpc_plugin
を使用しています。
以下で、register関数から情報を受け渡す対象の、「FrontierXMLRPC」コントローラクラスについて、説明します。
(3)「FrontierXMLRPC」コントローラクラス(RPC2.pm)追加
「FrontierXMLRPC」コントローラクラスは、(その1)で追加した、コントローラクラス(Method.pm)と、基本は一緒です。
- (1) XML-RPCリクエスト受信
- (2) Frontier::RPCライブラリに入力
- (3) Frontier::RPCライブラリから返却された、XML-RPCレスポンスを、まるごとWebクライアントに返却
「XML-RPCサーバ」のコントロールクラスと「FrontierXMLRPC」のコントローラクラスとの違いは以下の通りです。
- 起動時のregister関数から情報受信
stash->{frontier_xmlrpc_plugin}
取得 - コールバック実装追加
「stash」とは、Mojolicious上のアプリケーションで、現在のリクエストが使用する値を、保存するための領域です。
本プラグインでは、「FrontierXMLRPC」register関数(プラグイン開始時)で作成した情報を、アプリケーション経由でコントローラへ受け渡すための領域として使用しています。
frontier_xmlrpc_plugin
としたのは、本プラグインで名づけたものです。(もっといい方法があるのかもしれません)
コールバックは、HTTPリクエスト/レスポンスの記録用コールバックのために追加しています。
具体的な実装は以下の通りです。
XMLRPC controller package Mojolicious::Plugin::FrontierXMLRPC::Rpc2; use Mojo::Base 'Mojolicious::Controller'; use Frontier::RPC2; use Data::Dumper; sub proxy_xmlrpc { my $self = shift; my $plugin = $self->stash->{frontier_xmlrpc_plugin}; if ( ! defined $plugin ) { return; } my $methods = $plugin->{'method'}; my $server = $plugin->{'rpc2'}; my $cb = $plugin->{'cb'}; if ( ! defined $server or ! defined $methods ) { return; } my $body = $self->req->body; #translate from request(XML) to response my $response = $server->serve($body, $methods); #modify HTTP response $self->render(text=>$response, format=>"xml"); # callback if ( defined $cb ) { &$cb($body, $response); } } 1;
3.「FrontierXMLRPC」使用手順
「FrontierXMLRPC」をアプリケーションで使用する方法を示します。
3.1 インストール方法
以下の手順でインストールします。
$ cd Mojolicious-Plugin-FrontierXMLRPC $ perl Makefile.PL $ make $ make install
3.2 「FrontierXMLRPC」使用方法
「FrontierXMLRPC」は以下のように使用します。
(1)「FrontierXMLRPC」読み込み
「FrontierXMLRPC」を使用するには、アプリケーションのstartupにプラグインと、XML-RPC関数を登録します。
(2) XML-RPC関数登録
XML-RPC関数登録の方法は以下の通りです。
- XML-RPC関数の実装
- methodsの記述
methodsの記述方法は、[Frontier-RPC2]を参考にしてください。
(1)(2)を設定すると以下になります。
#XMLRPC コールバック sub callback { (my $req,my $res)=@_; } # This method will run once at server start sub startup { my $self = shift; #外部メソッド名と内部関数の紐付け設定 my $methods = { 'xml.rpctestplus' => \&xmlrpcplus , 'xml.rpctestminus' => \&xmlrpcminus , 'xml.rpctestmixed' => \&xmlrpcmixed }; #プラグインへのパラメータ my $xconf = { methods=>$methods, callback=>\&callback, }; $self->plugin('Mojolicious::Plugin::FrontierXMLRPC',$xconf); } #API sub xmlrpcplus { (my $a , my $b) = @_; } sub xmlrpcminus { (my $a , my $b) = @_; } sub xmlrpcmixed { (my $a , my $b) = @_; }
4. 「FrontierXMLRPC」のテスト方法
単体テストと、結合テストの手順を示します。
4.1 単体テスト
Mojoliciousには(フレームワークなので)単体テスト方法があります。
perlの通常の単体テスト方法とほぼ変わりません。
単体テストは以下のように行います。
$ perl t/01_load.t $ perl t/02_xml.t
01_load.tは、プラグイン実装が読み出せるかどうか、02_xml.tは実際にプラグインへ
XML-RPC関数を登録し、関数が呼び出せたかどうか確認しています。
実行すると以下のようになります。
$ perl t/01_load.t ok 1 - use Mojolicious::Plugin::FrontierXMLRPC; 1..1 $ perl t/02_xml.t This is callback $VAR1 = '<?xml version=\'1.0\'?> <methodCall> <methodName>xml.rpctestplus</methodName> <params> <param> <value><int>1</int></value> </param> <param> <value><int>2</int></value> </param> </params> </methodCall>'; $VAR1 = '<?xml version="1.0" encoding="UTF-8"?> <methodResponse> <params> <param><value><i4>6</i4></value></param> </params> </methodResponse> '; ok 1 - POST /RPC2 ok 2 - 200 OK ok 3 - content is similar 1..3
単体テスト全体を一度に行うなら、以下のようにします。
$ prove t/01_load.t .. ok t/02_xml.t ... ok All tests successful. Files=2, Tests=4, 2 wallclock secs ( 0.08 usr 0.05 sys + 1.61 cusr 0.27 csy s 2.01 CPU) Result: PASS
4.2 結合テスト
結合テストは、以下の手順で行いました。
- 「FrontierXMLRPC」をインストール
- テスト用アプリケーションにて、「XML-RPCサーバ」と同様の関数を定義
- テスト用アプリケーションを起動した後、XML-RPCクライアントを起動する。
サンプルにある、テスト用アプリケーションを起動した結果が以下の通りです。
$ cd t/combined/fxmlrpc_test/ $ script/fxmlrpc_test daemon --listen http://0.0.0.0:50030
xmlrpc_client.pyのURLを変更してアクセスした結果が以下です。
1 + 2 : 3 >xmlrpc_client.py 3 - 2 : 1 {'a': 'b', 'c': [1, 3, 2], 'b': 1500000000}
5. 終わりに
perlのお勉強として、Mojoliciousを題材にしました。
意外と手軽に扱えるので、いいのではないかと思います。