2011年3月6日日曜日

Google App Engine のための Gaelyk

現在、そして将来のJava™ 開発を方向付けている技術の側面を探っています。Java 開発 2.0 の前提となっているのは、開発のスピードが今までよりも速くなっていることです。これは、オープンソースの世界での急激な技術革新だけでなく、すぐに利用できるハードウェアが低価格で提供されるようになったおかげでもあります。(主にオープンソースのライブラリー、ツール、フレームワークでアセンブルされた) アプリケーションをホストするためのハードウェア・プラットフォームを他の誰かから借りれば、そのコストはインフラストラクチャーを購入して保守する場合の何分の一かで済みます。

を借りて Java アプリケーションを無料でホストさせるという概念を検討しましたが、この方法には柔軟性という点で、ある程度の犠牲が伴います。これに続く記事では、App Engine と Amazon EC2 との違いを学びました。先月の記事、「Groovy の RESTClient を使用して REST によって CouchDB の操作を行う」で取り上げたのはリレーショナル・データベースに代わる前途有望なデータベース、CouchDB です。CouchDB にはスキーマがないこと、そしてそのドキュメント指向という特質は新鮮に思えたかもしれませんが、実は、スキーマレスなデータ・ストアについてはすでに Google App Engine で動いているものを目にしていたのです。

今回は連載の始めに立ち返り、Google App Engine を再び取り上げます。オープンソースの世界はすでに App Engine の勢いに便乗し、このプラットフォームを対象としたアプリケーションの開発を容易にするためのフレームワークを次々と生み出しています。その 1 つが、Gaelyk と呼ばれるオープンソースのプロジェクトです。この記事を読むと、連載でこれまでに説明してきたさまざまな技術を活用した簡単なアプリケーションの構築が、Gaelyk によってさらに簡単になることがわかります。

新たな速さの鍵、それは軽量であることです

Google のインフラストラクチャーは概ね無料で使用できますが (前にも説明したように、ストレージ使用量が 500MB、そして毎月約 500 万件のページ・ビューに対応する帯域幅を超えると料金が発生します)、柔軟性に関しては犠牲が伴います。Google のインフラストラクチャーは Java 技術をサポートするものの、コアの Java ライブラリーおよび関連するオープンソース・ライブラリーのすべてをサポートするわけではないからです。しかも App Engine はプラットフォームであるため、開発は App Engine に合うように行わなければなりません。しかしここで、(驚くことではありませんが) オープンソースの技術革新が、Google App Engine を採用する際の障壁と考えられる問題を克服するために大いに貢献しているのです。

このようなことから新しく開始されたプロジェクトの 1 つが、Gaelyk です。この巧妙なフレームワークは、モデル・ビュー・コントローラー (MVC) パターンを正しく活用した軽量のアプリケーションをGroovy で容易に開発できるようにします。さらに Groovy のマジックを利用して使いやすさのための機能を App Engine の API にいくつか追加するだけでなく、Gaelyk は Google App Engine 対応 Eclipse プラグインと併せて使うことも可能です。Gaelyk によって、Google App Engine アプリケーションの開発、デプロイメントは、これ以上なく簡単になります。

Google での永続化

Google App Engine での永続化の実装についての情報は、ほとんど公開されていませんが、リレーショナル・データベースでないことは確かなので安心してください。ただし開発者のために言っておくと、永続オブジェクトの保存、読み取り、更新、削除は、通常の JDO (Java Data Object) コードを使って Google のプラットフォームから行うことも、さらには Google の下位レベルの永続化 API を使用して行うこともできます。

Groovy の RESTClient を使用して REST によって CouchDB の操作を行う」では、駐車違反切符システムを例に、ドキュメント指向データベースの特質を説明しました。その流れを引き継いで、この記事では駐車違反切符を作成、更新、削除するための Web アプリケーションを作成します。Google での永続化アーキテクチャーはドキュメント指向のアーキテクチャーではありませんが、スキーマがないという特質により、かなり柔軟なモデルに対応します。そこで、この Web アプリケーションでは駐車違反切符をできるだけ忠実にモデル化するために以下の情報を取り込むことにします。

  • 警官の名前
  • 日付
  • 場所
  • 違反内容
  • その他関連する注記

場所については汎用的なテキスト・ボックスのままにしておきます。というのも、違反が発生した場所は、例えば Best Buy の駐車場と記述されたり (訳注: Best Buy は、米国の代表的な家電量販店)、18 番通りと D 通りの交差点と記述されたりと、人によってさまざまな表現方法があるからです。要するに、詳細なフォーマットを決めても、そのフォーマットが必ずしもそこに記入される情報に適したものにはならないため、フォーマットを決めることはしないのです。

このアプリケーションの作成に取り掛かるには、Google App Engine 対応 Eclipse プラグインがインストール済みの状態でなければなりません (インストール手順については、「Google App Engine よ、こんにちは」を参照)。また、Gaelyk プロジェクトの Web サイト (「参考文献」を参照) から Gaelyk JAR ファイルをダウンロードする必要もあります。このダウンロードの配置場所を覚えておいてください。この後すぐ、ダウンロードを特定のディレクトリーに移動する作業が待っているためです。

Gaelyk フレームワークは Groovy を利用するため、Groovy の最新リリースも必要です。Groovy は単純な JAR ファイルであり、この記事を執筆している時点での最新リリースは groovy-all-1.6.5.jar となっています (「参考文献」を参照)。最後にもう 1 つ必要な作業として、Google App Engine の管理パネルでアプリケーション ID を作成してください (「Google App Engine よ、こんにちは」で作成したアプリケーション ID を使用しても構いません)。

次に、Eclipse 内で新規 Google Web アプリケーション・プロジェクトを作成し、「Next (次へ)」ボタンをクリックして適切な情報を入力します。その際には必ず、図 1 と同じように「Use Google Web Toolkit (Google Web ツールキットを使用)」オプションを選択解除してください。このツールキットは必要ないからです。


図 1. Eclipse での Google アプリケーション・プロジェクトの作成
Eclipse のダイアログ・ボックス内で、新規 Google Web アプリケーション・プロジェクトを作成します。 

Finish (完了)」ボタンをクリックすると、コード・ベースに取り掛かる準備ができます。

新しく作成したプロジェクトの war/WEB-INF/lib ディレクトリーに、Groovy と Gaelyk 両方の JAR をコピーします (図 2 を参照)。


図 2. Gaelyk に必要なライブラリー
新しく作成したプロジェクトの war/WEB-INF/lib ディレクトリーに、Groovy と Gaelyk 両方の JAR がコピーされた状態が示されている図です。 

Gaelyk を構成するには、WEB-INF/appengine-web.xml ファイルを編集して Google App Engine に追加情報を提供します。このファイルの先頭にあるアプリケーション・セクションに自分のアプリケーション ID を入力し、リスト 1 に記載するほんの数行の XML を追加してください。


リスト 1. App Engine の構成に必要な更新
<static-files>  <exclude path="/WEB-INF/**.groovy" />  <exclude path="**.gtpl" /> </static-files> 

上記のコードを追加することで、Gaelyk を使用する一環として作成することになる各種のファイルを、Google App Engine が静的に提供しないようにします。この後わかるように、Gaelyk はテンプレート・モデルを利用します。したがって、拡張子が .gtpl のファイルは JSP (JavaServer Pages) のような役割を果たし、App Engine ではなく Gaelyk フレームワークによって処理されます。

次に、同じく WEB-INF ディレクトリー内にある web.xml ファイルを開きます。これは、長年の間に開発者の誰もが愛着を持つようになった標準 Web アプリケーション構成ファイルです (このファイルは、App Engine および EC2 のそれぞれを最初に取り上げた記事でも扱いました)。このファイルでは各種のパターンをそれぞれ特定のサーブレットにマッピングしなければならないので、リスト 2 のような内容に更新します。


リスト 2. 更新後の web.xml ファイル
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns="http://java.sun.com/xml/ns/javaee" 	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"     version="2.5">  <servlet>   <servlet-name>GroovletServlet</servlet-name>   <servlet-class>groovyx.gaelyk.GaelykServlet</servlet-class>  </servlet>  <servlet>   <servlet-name>TemplateServlet</servlet-name>   <servlet-class>groovyx.gaelyk.GaelykTemplateServlet</servlet-class>  </servlet>  <servlet-mapping>   <servlet-name>GroovletServlet</servlet-name>   <url-pattern>*.groovy</url-pattern>  </servlet-mapping>  <servlet-mapping>   <servlet-name>TemplateServlet</servlet-name>   <url-pattern>*.gtpl</url-pattern>  </servlet-mapping>  <welcome-file-list>   <welcome-file>index.gtpl</welcome-file>  </welcome-file-list> </web-app> 

この web.xml ファイルでは、ウェルカム・ファイルを index.gtpl に指定していることに注意してください。したがって、Eclipse プラグインが自動的に生成した index.html ファイルを index.gtpl という名前に変更しなければなりません (Windows® で作業している場合は、ファイルを選択して F2 を押すと、名前を変更することができます)。

適切なライブラリーを所定の場所に配置し、上記で説明した 2 つの XML ファイルを両方とも正しく構成した後は、作業が順調に進んでいることを確認するために、index.gtpl ファイルを編集してリスト 3 の内容に合わせます。


リスト 3. 単純な GTPL ファイル
<html>  <head><title>A Simple GTPL</title></head>   <body>    <b><% print "Hello Gaelyk!".replace(" ", " from ") %></b>    <p>    <ol>     <% def wrd = "Groovy"        wrd.each{ letter ->     %>     <li><%= letter %></li>     <% } %>    </ol>    </p>   </body> </html> 

ご覧のように、Gaelyk の GTPL ファイル (つまり、Gaelyk/Groovy テンプレート) はまさに JSP のようなもので、スクリプトレットに振る舞いを追加することができます (この場合、振る舞いは Groovy です)。後からクロージャーと参照変数も使用できることに注意してください。

index.gtpl を保存してから、Eclipse でプロジェクトの基本ディレクトリーを選択して右クリックし、「Run As (実行)」を選択したら、先頭に青い g のロゴが組み込まれた「Web Application (Web アプリケーション)」オプションを選択します (図 3 を参照)。


図 3. Google Web アプリケーションとして実行
先頭に青い g のロゴが組み込まれた「Web Application (Web アプリケーション)」オプションが選択されている状態を示すスクリーンショットです。 

デフォルトでは、このランチャーは Jetty のローカル・インスタンスをポート 8080 で起動します。ポートを変更したい場合は、「Run Configurations (実行の構成)」オプションを選択し、プラグインが提供するオプション・パネルでポートを構成します。

Gaelyk Web アプリケーションのローカル・インスタンスが実行中になったところで、Web ブラウザーを開いて http://localhost:8080 にアクセスしてください。この愛らしい index.gtpl の出力は図 4 のようになっているはずです。


図 4. Hello world!
http://localhost:8080 でアクセスした index.gtpl の出力を示すスクリーンショットです。 

いとも簡単にアプリケーションを作成できたと思いませんか?

容易な永続化

この駐車違反切符システムは単純なもので、このシステムは違反切符を作成するための Web フォームと、違反切符を表示、削除、編集するための一覧表示機能を提供します。まずは、Gaelyk テンプレートを使って単純な HTML フォームを作成するところから取り掛かります。このフォームには create-ticket.gtpl という名前を付けます。図 5 に示すように、このフォームで取得しようとしているのは、個々の駐車違反切符に関するデータです。


図 5. 単純な駐車違反切符作成フォーム
何も入力されていない状態での単純な駐車違反切符作成フォームのスクリーンショットです。 

このフォームは Groovlet に対して送信されるので、プロジェクトの WEB-INF ディレクトリー内に groovy フォルダーを作成してください。ここが、Groovlet を配置する場所となります (「Google App Engine よ、こんにちは」でも同じ作業を行いました)。create-ticket フォームを送信すると実行されるのは、createticket.groovy ファイルです。このファイルを新しく作成した groovy ディレクトリー内に作成します。

確かに Gaelyk では JDO と JPA (Java Persistence API) コードを使用することができますが、使用するデータ・ストアとのインターフェースを取るには他の手軽な手段があります。それは、Google の Entity オブジェクトを使用することです。Gaelyk チームは Groovy のマジックによって Entity オブジェクトを強化し、永続オブジェクトを驚くほど簡単に操作できるようにしました。

この例の場合、create-ticket.gtpl ページから送信されたフォームの要素を取得して、システム内で新しい違反切符を作成しなければなりません。Entity クラスを使用すれば、違反切符を表すために POJO のようなオブジェクトを定義しなくても済みます (「Google App Engine よ、こんにちは」では、JDO オブジェクト Triathlon を定義しました)。そのため単純に Groovy 流に違反切符をモデル化して保存できるので、ほとんど手間がかかりません。

したがって、フォームが送信したパラメーターを Gaelyk の便利な params オブジェクト (ちなみに、Grails でもこのオブジェクトを提供しています) によって取得し、Entity インスタンスを作成することができます (リスト 4 を参照)。


リスト 4. Entity の作成
def formatter = new SimpleDateFormat("MM/dd/yyyy") def offensedate = formatter.parse("${params.of_month}/${params.of_day}/${params.of_year}")  def ticket = new Entity("ticket") ticket.officer = params.officer ticket.license = params.plate ticket.issuseDate = offensedate ticket.location = params.location ticket.notes = params.notes ticket.offense = params.offense 

ticket 変数は Entity のインスタンスであることに注意してください。"ticket" ストリングは、作成したエンティティーの種類を表しています。これは違反切符を検索する際に役立ってきます。次に、魔法のごとく自動的に、プロパティー値が違反切符と関連付けられた Entity インスタンスに割り当てられます。これで、ticket.officer が Web ページのフォームから送信された officer パラメーターの値を表すというわけです。フォームには日付を入力するフィールドが 3 つあるので、SimpleDateFormat を使って日付のインスタンスを作成し、その値を issueDate に設定します。

以上で、違反切符を表すオブジェクトは完成しました。後はこのオブジェクトを次のコマンドを使って保存すればよいだけです。

ticket.save() 

違反切符を永続化したら、今度は違反切符を表示可能なページをユーザーに表示する番です。これも簡単なことで、ただ単に (処理のために) view-ticket Groovlet にリダイレクトするだけです。

redirect "viewticket.groovy?id=${ticket.key.id}" 

上記のコードを見るとわかるように、ここでは id というパラメーターを作成し、その値を保存された違反切符インスタンスのキー (Google App Engine が生成したキー) に設定しています。このように、create-ticket Groovlet は簡潔ながらも極めて機能的に仕上がっています。そしてこの一連の作業を容易にしているのが Gaelyk です。

容易な表示

前の例では、ticket インスタンスを作成した後、続いてリクエストを別の Groovlet にリダイレクトしました。違反切符の表示を容易にするこの Groovlet には、Google App Engine を読み取るコードが記述されています。リクエストと一緒に渡された id が、新しく作成されたインスタンスを検索するために使用されます。この例では Google の KeyFactory を使って Google の Key オブジェクトのインスタンスを作成します。作成された Key は、Gaelyk がフレームワーク内の Groovlet インスタンスのバインディングに自動的に追加した datastoreService を介して、対応する ticket インスタンスを検索するために使用されます (リスト 5 を参照)。


リスト 5. Entity を表示するコード
import com.google.appengine.api.datastore.KeyFactory  if (params["id"]) {  def id = Long.parseLong(params["id"])  try {    def key = KeyFactory.createKey("ticket", id)    def ticket = datastoreService.get(key)     request.setAttribute "ticket", ticket     forward "viewticket.gtpl"     } catch (Throwable t) {     //forward to some error page...    } } else {  forward "index.gtpl" } 

対応する ticket インスタンスが見つかると、その違反切符を組み込んだ (すでに Groovlet に存在する) HTTP request オブジェクトが viewticket.gtpl ページに渡されます。Web アプリケーションの他のあらゆる JSP と同じく、この Web ページも、渡された違反切符に関連付けられた属性を表示します。

リスト 6 を見るとわかるように、Gaelyk は include をサポートします。これはつまり、通常の JSP での場合と同じく、.gtpl ファイルに他のファイルを組み込めるということです。同様に、すべての .gtpl ファイルで HTTP Request オブジェクトのインスタンスを (request変数を介して) 使用できるのです。


リスト 6. 1 つの Entity GTPL を表示するコード
<% include "/WEB-INF/includes/header.gtpl" %>  <% def ticket = request.getAttribute("ticket") %>  <div class="info">  <h2>Parking Ticket</h2>  </div>  <table> <tr> 	<th>Issuing Officer</th> 	<th>Vehicle Plate</th> 	<th>Date</th> 	<th>Offense</th> 	<th>Location</th> 	<th>Notes</th>   </tr>  <tr> 	<td>${ticket.officer} </td> 	<td>${ticket.license}</td> 	<td>${ticket.issuseDate}</td> 	<td>${ticket.offense}</td> 	<td>${ticket.location}</td> 	<td>${ticket.notes}</td>   </tr>  </table>  <% include "/WEB-INF/includes/footer.gtpl" %> 

これまでの説明で納得してもらえたと思いますが、Gaelyk は Google App Engine で軽量の Web アプリケーションをいとも簡単に作成できるようにします。さらに、App Engine の永続ストアでの操作もこれ以上ないほど簡単です。一方、Entity オブジェクトを操作する際に使用する下位レベルの API は使い慣れるまでに少し苦労します。また、クエリーにはある程度頭を使わなければなりません (ある意味、CouchDB でクエリーを行うようなものです)。例えば、作成済み違反切符の一覧を表示するには、リスト 7 のようなコードが必要になってきます。


リスト 7. 一連の Entity を表示するコード
import com.google.appengine.api.datastore.Query import static com.google.appengine.api.datastore.FetchOptions.Builder.withLimit  try {  def query = new Query("ticket")  query.addSort("issuseDate", Query.SortDirection.DESCENDING)  def preparedQuery = datastoreService.prepare(query)  def tickets = preparedQuery.asList( withLimit(10) )   request.setAttribute "tickets", tickets forward "index.gtpl" } catch (Throwable t) {  forward "index.gtpl" } 

リスト 7 では、App Engine の Query オブジェクトを利用しています。見てのとおり、クエリーにソートのような機能を追加することも、さらには返される結果の数を制限することも可能です。SQL はまったく使用していませんが、データは確実に保管されているので、多少方法は異なるとは言え、データを取得することができます。

Google App Engine よ、こんにちは」での場合と同じく、クラウドへのデプロイメントは至って簡単です。プラグインで「Deploy App Engine Project (App Engine プロジェクトのデプロイ)」をクリックするだけで、後の作業は Google がすべて引き受けてくれます。実際、記事に付属のコードをダウンロードして、この方法でそのままデプロイしても構いません。このコードが、この 1 回の記事では説明し切れなかった部分を補ってくれるはずです。例えば、付属のコードには違反切符の削除を実装して、違反切符システムでのユーザー操作を少し改善してあるので、Gaelyk の動作をもう少し詳しく確認できるはずです。

迅速で、しかも容易になった開発

オープンソースの技術革新に支えられたクラウドおよびスキーマレスなデータ・ストアが、Java 開発の未来像の一端を担っていることは確実です。この 2 つはいずれも容易に採用できるようになっています。実際、この記事の例で使用したハードウェアとソフトウェアはどちらも完全に無料です。Google が料金を請求するようになったら (Web アプリケーションに月 500 万件のヒットがあるということは、かなりのトラフィック量です)、それは着実に成功に向かっていることを意味します。そして迅速な Web 開発をさらに加速させるのが、Gaelyk フレームワークです。Java 開発はまさに進化の一途を辿っていると思いませんか?


参考文献

学ぶために

  • Gaelyk: Google App Engine for Java に対応したこの軽量の Groovy ツールキットについて詳しく学んでください。

  • Google App Engine: Google App Engine のホームにアクセスしてください。

  • Java 開発 2.0: Google App Engine よ、こんにちは」(Andrew Glover 著、developerWorks、2009年8月): Java 開発 2.0 の概要と、そのコンセプトを Google の App Engine for Java を利用して素早く実現する方法を理解してください。

  • 連載「実用的な Groovy」(Andrew Glover、Scott Davis 共著、developerWorks): この連載記事では、実用的な Groovy の使用方法を探り、それぞれの方法をいつ、どのようにして効果的に適用するかを伝授しています。

 

  • Gaelyk: 最新の Gaelyk JAR をダウンロードしてください。

  • Groovy: Groovy を今すぐダウンロードしてください。

  • The Google Plugin for Eclipse: Google App Engine 対応 Eclipse プラグインをダウンロードしてください。

0 件のコメント:

コメントを投稿