まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

とある人からBlueMix で開発すると何かいいことあるの?」と聞かれたので、その答をこのブログエントリに書いておきます。 まあ答は BlueMix というよりも、CloudFoundry 全般に言える内容なんでしょうけど。

この質問者の意図は「オンプレミス環境や IaaS 環境でアプリ開発した場合と比較して、BlueMix だとどれだけ楽に作れるの?」ということだったようです。Java アプリ開発に特化した内容はないのですが、BlueMix に興味を持っている層の人は Java が比較的多いのかな、と思ったので、一応 Java 開発者向けの前提で書いてみます。


で、僕の答はシンプルで「特別変わらない。そしてそれが素晴らしい」です。

「変わらないことが素晴らしい」とは、少し分かりにくいかもしれません。多少くどい話になってしまいますが、これは BlueMix ではない他の PaaS と IaaS 間の移植を考えたケースと比較すると分かりやすいかもしれません。

例えば Google App Engine  というグーグルの PaaS 環境があります。言語としては Java / Python / Go が使えて、データストアも KVS 型と SQL 型が選べて、メッセージング機能が含まれていたりする上に、負荷に合わせて勝手にスケールアウトしてくれます。しかもある制約の範囲内で利用する限りは無料! というなかなか魅力的な環境です(個人的にも使ってます)。

ただ大きな悩みが1つ。他の環境とのポータビリティがほとんどないのでした。App Engine というパブリックな PaaS 環境内で使う前提であればこれは問題にならないのですが、(一部でも)自社サーバー環境で構築し直したいとか、サーバーはどこぞのクラウドのを使いたいとか、そういった要件にそのまま対応ができないのでした。言語として Java が使えると書きましたが、一般的な意味での Java アプリケーションとは少々違うもの(というか、App Engine 専用の Java アプリケーション)なのです。

で、「とはいえ同じ Java で作ったウェブアプリケーションなんだから、移植すればいいのでは?」という発想にたどり着きますが、これがまたややこしい話というか・・・ 確かに同じ言語を使ってはいますが、アプリケーションとして全然違うもの(Eclipse レベルの話をすると、最初に新規作成するプロジェクトからして別モノ)です。AppEngine 環境では専用の Base64 エンコーダー/デコーダーなど色々便利なライブラリが付属してはいるのは事実なんですが、それらを使ってしまうと移植時には全く別の手段を探すことになってしまうのでした。なお同じことが一般的な Java アプリケーションを App Engine 向けに(逆向きに)移植する場合でも同じことが言えます。

僕自身は過去に2度、App Engine プロジェクトを一般的な Java アプリケーションプロジェクトに移植した経験があります。(制約面では厳しい環境から緩い環境になるので)たしかに出来ないことではないし、同じ言語なので一部コピペが使えるのも事実ではあるのですが、やはりどうしても移植しきれなくて、一部機能だけは App Engine に残して併用する、という運用を今も続けていたりします。

これは App Engine が悪いというわけではなく、それだけ便利な環境を提供してくれていることの裏返しでもあるのですが、その便利さに頼ってしまうと後戻りができなくなってしまう、ということだと思っています。いわゆる「ベンダーロックイン」です。ないとは思っていますが、もしも Google が App Engine というサービスを止めてしまった場合、もうこのサービスは諦めるか、腹をくくって同じ機能をゼロから作り直す必要があると思っています。

同じことはセールスフォースの force.com プラットフォームにも言えます。一応 Java ライクな言語でアプリ開発ができる、ということになっていますが、これはセールスフォース独自の APEX という、ちょっと違う言語を使うことになります。実際に移植経験があるわけではないのですが、移植性とかの話になるとかなり厳しいのではないかな、と思っています。

そしてこれは App Engine や force.com に限ったことではなく、PaaS という OS やミドルウェアの概念を意識させないような便利なプラットフォームサービスを利用する以上は避けて通るのが難しいものだと思っていました。現に IaaS や SaaS などと比べて、その中間に位置する PaaS についてはどのベンダーも苦戦気味ですが、それはこういった「資産を移植しにくい」という背景も関係しているのだと思っています。


・・・なんか長くなってしまいました。話を冒頭に戻します。

私自身が BlueMix を使って感じた特徴の1つ、それは「オンプレミス環境や IaaS 環境とのポータビリティ」だと感じてます。オンプレミス用に作成したり、現にいま Amazon EC2 環境で動いている Java アプリケーションが、ほぼ変更なしにそのまま BlueMix で動かすことができる、ということです。もちろん例外的なケースもあるとは思いますが、一般的なウェブアプリケーションであれば、バイナリの WAR ファイルをほぼそのまま(ケース次第では1バイトも変更せずに) BlueMix / 各種 IaaS / オンプレミス環境全てにデプロイ出来る、ということも可能になります。

特に Java アプリケーションの(オンプレミスや IaaS 用の)資産が手元にある場合、BlueMix では WebSphere Application Server をベースとした(と思われる)"Liberty for JAVA" という Java アプリケーションサーバー環境を標準提供しています。この辺りは IBM の得意分野でもあるのでしょうが、我々開発者や開発ベンダーが持っている Java アプリケーション資産を動かすための準備は既に提供されていることになります。

冒頭で「(BlueMix は他の環境と比べて)特別変わらない、それが素晴らしい」と書いたのはまさにこのことです。オンプレミス/IaaS を選ぶお客様もいれば PaaS 環境を選択するお客様もいます。開発者はその2つの環境用に異なるアプリケーションモジュールを準備しておく必要があります。でもその PaaS が BlueMix や CloudFoundry であれば、その適応のための変更という作業はほぼ不要になります。もしかしたらそのまま動いてしまうかもしれません。これがメリットでなくて何?ということを言いたかったのでした。


そしてもう1つの特徴、それは「オープン」であることです。BlueMix はオープンソースの CloudFoundry V2 をベースに作られています。そのため万が一 IBM が BlueMix サービスを打ち切ることがあっても、PaaS 環境としての CloudFoundry に移して運用を続けることもできますし、自社に CloudFoundry 環境を構築してオンプレミスな PaaS 環境(?)の上で運用を続けるという選択肢もあります。更に CloudFoundry の活発なコミュニティの中で開発・提供されている便利なツールや資料など、コミュニティのパワーを借りることができることもオープン環境の強みだと思っています。

アプリケーションを開発する立場では複数環境用の移植メンテナンスがほぼ不要で、シングルソースのまま各種環境向けの提供できるようになります。 また運用する側も CloudFoundry コミュニティから提供される各種情報を便りに、場合によってはコスト比較をしながら運用環境や体制を変えていくこともできるようになります。少し前の PaaS では考えにくかったこんなことが今はできるようになっているのでした。

もちろんこれだけではないのですが、こういったオープン性を背景にしたことによる BlueMix のアドバンテージは計り知れないと感じています。繰り返しになりますが、オンプレ/IaaS 用に開発された Java アプリケーションの WAR ファイルがもしかしたらそのまま、そうでなくても最小限の変更で PaaS 上で動くかもしれない、というのはやはり魅力的です。今は本家 CloudFoundry も有償版しかないので、無料で CloudFoundry が試せる環境という意味でも BlueMix はなかなかおいしくて気にいってます。CloudFoundry や PaaS に興味を持っているアプリ開発者の方は、BlueMix という名の CloudFoundry を試してみて、手元のアプリがどれだけ動くのか、動作確認だけでも早めにやっておくといいかもしれません。今なら無料なので(笑)。





 

こんなニュースがありました:
グーグルが「Gmail」の利用規約を更新 - メール内容の解析を明示

グーグルは Gmail に書かれた内容を読んでいる、ということ。
その是非が色々言われているようですが、その件についてコメントは控えます。

僕は知ってました。というか、そういうものだと思ってました。
普段から自分でいくつかのウェブサービスを遊びで開発して公開したりしてます。
ある時、まだ誰にも話してないし、リンクも作っていない作りたてのウェブサイトのURLを Gmail で知り合いに送った所、その数日後から Google のクローラーボットがやってくるようになりました(苦笑)。本当にこのメールがきっかけだったのかどうかは分からないのですが、原因がメール内容しか思い当たらなかったので、以来そういうものだと思っていました。

で、それを逆手にとったというわけではないですが、裏ワザを1つ紹介します。

これから公開しようとしているウェブサービスを開発したら、公開前にわざと GMail にその URL を書いて誰かに(例えば自分の別のアドレスに)送ります。それでグーグルはその新サービスの URL を知ることになるので、数日中にクローラーボットが送り込まれて、グーグルの検索エンジンにインデックスしてくれます。

これで、サービスがスタートする際には既にサービス内の大半のページがグーグル検索結果に表示される状態を作っておくことができます。厳密には、サービススタート前に(キーワード次第では)検索結果に表示されるのはともかく、実際に訪問されては困る、ということもあると思います。そういう場合は UserAgent を見て、グーグルボットの場合だけは訪問を許し、それ以外の場合はエラーにする、という処理を加えておいて、サービス開始直前に無効にする、といった対策で訪問を回避することもできます。


と、まあグーグルが勝手にメールを解析してくれるのであれば、それを勝手に有効活用させてもらいましょう、という方法でした。


 

最初にお断りしておくと、今回紹介する機能は通話の API サービスで、実際に試すと少額ですが以下の料金が発生します。その点ご了承ください:
http://twilio.kddi-web.com/price/index.html



Twilio という変わり種サービスがあります:

http://twilio.kddi-web.com/


↑この URL を見てもわかるように、日本では KDDI ウェブコミュニケーションズ様がサービスを提供しています。

Twilio は「クラウド上の電話 API サービス」です。ウェブ上から電話をかけたり、特定の番号への着信を受けて(自動音声などで)処理したり、ということができるのですが、そのプログラミング用 API が公開されていることで開発者視点からも興味深いサービスです。なお、Twilio API の公式ドキュメントについてはこちらを参照ください:
http://www.twilio.com/docs/api/twiml


更に、最近 IBM がベータ公開している PaaS 環境である BlueMix の中で、この Twilio が連携サービスの1つになっていることが分かりました。BlueMix はアメリカの IBM が提供しているサービスで、日本で取得した Twilio アカウントが使えるか心配でしたが、私が使っている限りでは特に問題ないようです。 というわけで、この BlueMix のサービスとして Twilio を使った電話連携アプリを作る様子を紹介してみます。


BlueMix では Twilio サービスが提供されていますが、使うためにはあらかじめ Twilio のトライアルアカウントを取得しておく必要があります。既にアカウントをお持ちの方は自身のアカウント ID と認証トークンを確認してください。Twilio のアカウント作成に関しては Micorsoft のページに詳しく記載されていたので参照ください。こちらの手順でアカウント ID と認証トークン、そして通話用の電話番号(!)が取得できます:
Twilio (トゥイリオ)を触ってみた

ここで一点注意を。通話用の電話番号はトライアルアカウントの範囲内で取得できますが、その番号では SMS は利用できません。SMS 用の電話番号を取得するには初期チャージ料金 2000 円と、月額10ドルの番号維持費が必要になります。


Twilio のアカウントが取得できたら、そのアカウントを使った Twilio サーバーを BlueMix 上に作成します。まずは BlueMix にログインし、ダッシュボードから "Add a service" を選択します:
2014040401


サービスの種類は "Twilio" を選択します:
2014040402


確認画面で "ADD TO APPLICATION" を選択します:
2014040403


Twilio サービスの簡易設定を行います。といってもここで設定する項目は3つだけで、下の2つは Twilio アカウント作成時やログイン後の画面から取得できるものです。入力後に "CREATE" をクリックします:
 - Add to: アプリケーションサーバーの指定。後で指定する場合は "Do not associate" でも構いません。
 - Account SID: Twilio API を利用する アカウント ID
 - Auth Token: 認証トークン文字列
2014040404


先ほどの手順でアプリケーションサーバーの指定をしなかった場合は別途アプリケーションサーバーを作って(あるいは既存のものを使って)Twilio サーバーと紐づけます。ここでは kkimura3 という名前の Java アプリケーションサーバーを作って、そこに紐づける前提で紹介しています。アプリケーションサーバーの "Add existing service" を選択します:
2014040405


紐づけるサービスを選択します。今回は上記で作成した Twilio サーバーを指定します:
2014040406


アプリケーションサーバーを再起動する、という確認画面が出たら OK をクリックします:
2014040407


アプリケーションサーバーが再起動し、Twilio のマークが表示されればサービスと紐づいていることが確認できます:
2014040408


この紐づいた状態で kkimura3 サーバーの環境変数を確認すると、VCAP_SERVICES 変数に Twilio アカウントや認証トークンが設定されていることが確認できます。したがって、この後作成するアプリケーションにはこれらの情報をハードコーディングする必要がなく、環境変数から取得する、というセキュアな手法も可能になります:
2014040409


また、Twilio API の SDK をダウンロードしておきます。各種言語の API はこちらに用意されています:
Twilio API Libraries

今回は Java を利用するので、ページの真ん中くらいの "Java" というセクションから "twilio-java" と書かれた箇所をクリックし、リンク先から最新版の Java SDK をダウンロードします(2014/04/04 時点では twilio-java-sdk-3.3.16.jar が最新版です)。
2014040410

あとは普通に(Eclipse などで) Java アプリケーションを作成します。その際に今ダウンロードした Twilio Java SDK ファイルをプロジェクトに(WEB-INF/lib/ とかに)インポートして、プロジェクト内で利用できるようにしておきます。さあこれで準備は完了です!


で、Twilio 連携アプリケーションを作るわけですが、今回は以下のような仕様のシンプルなアプリを作ります:
- 「指定の番号へ電話をかけて、特定のメッセージを流す」というアプリ。
- 発信元番号は Twilio で取得した番号(日本で取得した場合は 050-AAAA-BBBB という、050 で始まる番号になっているはずです)。
- 着信先番号はアプリ内で指定する(ただし自分で受け取れないと意味ないので、自分の携帯電話番号とか)。

以下でそのアプリのコードを紹介しますが、かなりシンプルなのがわかると思います。

なお、日本の電話番号はゼロから始まる(0**-****-****)のですが、Twilio から発信する場合は国際電話形式に変更する必要があります。そのため最初のゼロをとり、頭に +81 を付け、+81-**-****-**** という形式の電話番号をコード内で指定している、という点に注意してください。


Twilio 連携をするアプリケーションをこんな感じで作成します。今回は JSP ファイル(twilio.jsp)を1つ作成し、以下のような内容にしてみました:
<%@page import="java.util.*" %>
<%@page import="java.net.*" %>
  :
<%@page import="com.twilio.*" %>
<%@page import="com.twilio.sdk.*" %>
<%@page import="com.twilio.sdk.resource.factory.*" %>
<%@page import="com.twilio.sdk.resource.instance.*" %>

<%
String sid = "", token = "";
String env1 = System.getenv( "VCAP_SERVICES" );
if( env1 != null && env1.length() > 0 ){
  // BlueMix 環境なので、env1 から accountSID と authToken の値を取り出し、sid / token に格納する
    :
}

//. BlueMix でない環境のための設定
if( sid.length() == 0 ){
  sid = "(Twilio のアカウントSID)";
}
if( token.length() == 0 ){
  token = "(Twilio の認証トークン)";
}

String r = "";
try{
  TwilioRestClient client = new TwilioRestClient( sid, token );
  Map params = new HashMap();
  params.put( "To", "+8180xxxxyyyy" );  // +81-80-XXXX-YYYY 形式での(自分が受け取れる)電話番号
  params.put( "From", "+8150aaaabbbb" ); // +81-50-AAAA-BBBB 形式での Twilio で取得した電話番号
  params.put( "Url", "http://demo.twilio.com/welcome/voice/ja/" ); // 確認用ウェルカムメッセージ
  CallFactory callFactory = client.getAccount().getCallFactory();
  Call message = callFactory.create( params );  // 実際に電話をかける
  r = "" + message.getSid();
}catch( Exception e ){
  e.printStackTrace();
  r = "Exception: " + e;
}
%>

result = <%= r %>

ここでの内容はシンプルなので眺めていればなんとなくわかると思います。発信番号と着信番号を指定して、着信するとウェルカムメッセージを流す、というだけの内容です。また成功した場合のウェブ画面には SID が表示されるようになっています。

ちなみに上記コード内の params.put( "Url", "***" ); で指定した箇所ですが、Twilio ではメッセージの内容を特定のフォーマット(TwiML)で定義するのですが、その定義内容が参照できる URL を指定することで、そのメッセージを音声で喋らせることができます。上記で指定しているのはデフォルトの確認用メッセージ(「トライアルアカウントへようこそ・・」みたいな感じ)が流れる URL ですで、その中身は以下のようになっています:
<Response>
<Say language="ja-JP" voice="alice">VOICE U R L の設定を変更することでこの文章を変更できます。</Say>
<Pause length="1"/>
<Say language="ja-JP" voice="alice">仕様のことでご不明点が御座いましたらご連絡ください。</Say>
</Response>

この内容は自分でオリジナルのものを定義/用意することも可能ですし、TwiML を生成/保管するサービスも提供されているようです。TwiML の仕様についてはこちらを参照するか、あるいはウェブで情報を探してみてください。


こうして作成したウェブアプリケーションを WAR ファイル(twilio.war)にして、上記で作成した BlueMix の kkimura3 サーバーに cf を使ってデプロイします(この辺りの詳しい手順はこちらを参照ください):
# cf push kkimura3 -p twilio.war

そして、ウェブブラウザで BlueMix のアプリケーションサーバーの twilio.jsp にアクセスすると、画面には SID が表示されて・・・
2014040411


そして携帯電話には Twilio の番号からの着信が・・・
写真


おお! できました!! このコールを着信すると機械的な声で Twilio のデモメッセージが(自分で作ったメッセージの URL を指定した場合はそのメッセージが)音声で流れてきます。つまりウェブアプリから電話番号に発信してメッセージを流す、というアプリがこんな簡単に作れてしまったことになります。


このアプリは放置しておくと1アクセスごとに電話がかかってきて(しかも19円ずつかかって)しまうので、検証が終わった段階で止めておくのがいいでしょう。でも電話や SMS の連携が数行のコードでできてしまうのはアプリ開発の幅が広がりますよね。

そしてそんな Twilio サービスを自分のアプリ用に、しかも選択するだけで簡単に用意できてしまう BlueMix プラットフォームにも可能性を感じました。




このページのトップヘ