OpenWhiskとは
OpenWhiskは、マイクロサービスを実装するための手段の一つである Function as a Service
です。一般的にServerlessという表現がさえれることも多いです。実際にOpenWhiskでは、処理(Action)=Functionを動かすためのプラットフォームでありユーザが server
を意識することはありません。
OpenWhiskは、OSSで提供されており自身のサーバ環境にインストールして動作させることが可能です。今回のハンズ・オンではOpenWhiskのサービスを提供している IBM Bluemix PaaSを利用して行います。
以下に私の書いたドキュメントがありますので参考にして下さい。
事前準備
今回の作業内容
ハンズ・オンでは代表的なOpenWhiskの動作を学ぶために以下のようなアプリケーションを作成します。
- JsonデータをCloudantに投入する(この際に
text: "message"
を入れておく) - New Documentが作成されたCloudantはOpenWhiskと連携し処理を起動する(Trigger/Feed)
- OpenWhiskの処理(Action)が呼出され作成された文書を読み出します
- 最終的に読み出した文章の
text
の内容を Slackへ通知します。
従来であればこのようなアプリケーションを構築する際には、Jsonデータを投入する処理側でSlackへ通知する機能を組み込むことや定期的にCloudantの状態を監視する必要がありましたがOpenWhiskの仕組みを利用することで処理を実装することが可能となります。
はじめに
OpenWhisk Cliの導入
- Bluemixのコンソールにログインしてください。
- CLIのダウンロード からダウンロードを行います。
- ダウンロードを実施し、wskコマンドをパスが通った適当な箇所にコピーします。
- 以下のコマンドを実行して初期化を行います(この引数は先程のダウンロードのサイトに表示されています、個々人で値が違うので以下のコマンドはコピーしないようにしてください)
- 画面上にキーが表示されない場合があります、原因は不明ですがアカウントの問題の模様です。継続的に利用している場合にはBluemix上のチケットで問い合わせをしてください。今回限りの場合にはお手数ですが再度 IBMidを発行してトライしてみてください。
wsk property set --apihost openwhisk.ng.bluemix.net --auth 367d53c0-1448-4c09-a49f-7c7f3f9b5c67:1EJoKPrEFKNZguKsUqYLfEktnBajdbDU1VpfOtO1jVUYwHnWtGJIc2V7mOl8adafq
次にNamespaceをリセットします。(初めて実施する人は不要かとおもいますが一応入力しておいてください。過去に利用したことがある場合には必須です)
wsk property unset --namespace
動作確認のために以下のコマンドを実施して見て下さい
wsk action invoke /whisk.system/utils/echo -p message hello --blocking --result
Json形式で結果が hello と出てくれば動作しています。
Cloudantの準備
Dashboardから、「カタログ」を選択します。
「Cloudant NoSQL DB」を選択します。以下の情報を設定して「作成」をクリックしてインスタンスを開始します。
- サービス名: handson-cloudant
- 資格情報名: Credentials-1 (ディフォルト)
- プラン: Lite (無料)
正常に開始されると以下の画面が表示されます。「LAUNCH」をクリックしてコンソールを起動します。
コンソールは以下のようになっています。
ひだりのメニューから「Database」を選択します。
今回利用するための新規のデータベースを作成する為に「Create Database」をクリックしデータベース名handson-openwhisk-db
を入力してデータベースを作成します。
作成が正常にされると以下のようになります。
この画面は後でデータの投入を行う際に利用するのでブラウザをそのままにしておいて下さい。仮にブラウザをクローズしてしまった場合にはBluemixの管理コンソールから再度開くことが可能です。
サービス→ダッシュボードを選択しサービスを探すと先ほど作成したインスタンスを見つけることが出来ます。
これでCloudant NoSQL DB側の準備はおわりです。
Slackの準備
Slack側では外部からメッセージを投稿するために「Incorrect Webhock」という機能を利用します。
上記のTEAMNAME
は各自の自身のアドレスを利用して下さい。
Manageのメニューから「Custom Integration」を選択します。
次に、「Incoming WebHook」を選択します。
新しい接続をつくるため「Add Configuration」を選択します。
接続をおこないたいチャンネルを選択して「Add Incomming WebHooks integaration」をクリックします。
上記で表示される「WebHook URL」をコピーして保管しておきます。
これでSlack側の準備は終わりです。
実際の作成
Cloudantの新規ドキュメントの作成を継起にActionを実行する
まずはCloudantに新規ドキュメントが作成されたことを検知してActionを実行する部分の流れを作成していきます。ここでは実行するActionを handson-read-document
として作成します。
まずは新規のActionを作成するためにwskコマンド
を利用します。(Macの場合にはTerminalなど、Windowsの場合にはコマンドプロンプトなどを利用します)
function main(params) {
var msg = {};
msg.docid = params.id;
msg.dbname = 'handson-openwhisk-db';
return msg;
}
上記の内容を handson-read-document.js
としてエディタを利用して作成してください。
次に以下のコマンドを利用して action を作成します。
$ wsk action create handson-read-document handson-read-document.js ok: created action handson-read-document
動作の確認
入力として以下の内容を先ほど作成した action に対して渡してみたいと思います。
{
"id" : "0001"
}
コマンドラインでは以下の用になります。引数で -b
を利用すると同期で回答を得ることができます。つけない場合には実行結果を待たずに処理が終了し結果が格納されたアクティベーションIDが表示されます。 -r
では結果のみを表示しますが、つけない場合には処理のログが表示されます。パラーメータは -p
で指定します。
$ wsk action invoke handson-read-document -b -r -p id 001 {
"dbname": "handson-openwhisk-db",
"docid": "001"
}
Cloudantの文書を読み込む処理を追加する
先ほどの作成したActionにつづいて、Cloudantの文書を読み込む処理を追加します。この処理を行うためにはコードを書く必要はなく既に用意されているPackageを利用します。OpenWhiskには多数のPackageが用意されておりコレを利用することでコードの再利用が可能です。
利用できるパッケージ内容は次のコマンドで表示できます。
$ wsk package list /whisk.system packages
/whisk.system/alarms shared
/whisk.system/messaging shared
/whisk.system/cloudant shared
/whisk.system/pushnotifications shared
/whisk.system/websocket shared
/whisk.system/slack shared
/whisk.system/watson-translator shared
/whisk.system/weather shared
/whisk.system/utils shared
/whisk.system/samples shared
/whisk.system/watson-textToSpeech shared
/whisk.system/watson-speechToText shared
/whisk.system/github shared
/whisk.system/watson shared
/whisk.system/system shared
/whisk.system/util shared
Cloudantパッケージ中には幾つものActionなどが設定されています。
$ wsk package get --summary /whisk.system/cloudant package /whisk.system/cloudant: Cloudant database service
(parameters: bluemixServiceName, dbname, host, overwrite, password, username)
action /whisk.system/cloudant/delete-attachment: Delete document attachment from database
(parameters: attachmentname, dbname, docid, docrev, params)
action /whisk.system/cloudant/update-attachment: Update document attachment in database
((略))
このPackageに対して初期値を与えることで実際のサービス(今回の場合にはCloudatNoSQLのhandson-cloudant
データベース)と紐付ける必要があります。Cloudantパッケージの場合には、DB名やユーザ名、パスワードを設定する必要があります。この設定された状態を bind
する言います。この操作を簡略化するためにBluemix上に設定されているサービスを捜査してBindしてくれるために refresh
コマンドが用意されています。
$ wsk package refresh _ refreshed successfully
created bindings:
updated bindings:
Bluemix_handson-cloudant_Credentials-1
deleted bindings:
作成されたパッケージを表示してみます。
$ wsk package list packages
/atg_tokida/Bluemix_Weather Company Data for IBM Bluemix-bm_Credentials-1 private
/atg_tokida/Bluemix_Push Notifications-jf_Credentials-1 private
/atg_tokida/Bluemix_cloudant-for-darkvision_Credentials-1 private
/atg_tokida/Bluemix_openwhisk-test_Credentials-1 private
/atg_tokida/Bluemix_handson-cloudant_Credentials-1 private
設定された内容をみるには wsk package get /atg_tokida/Bluemix_handson-cloudant_Credentials-1
コマンドを実行して parameter 項目を見ると設定がわかります。
今回は Cloudant の文書id を引数にドキュメントの内容を読み込みたいと思いますので read-document
actionを利用します。
action /atg_tokida/Bluemix_handson-cloudant_Credentials-1/read-document: Read document from database
(parameters: dbname, docid, params)
先程の action handson-read-document
と上記の action をつなげて見ます。
以下のコマンドで新しい action を作成します。
$ wsk action create --sequence handson-read-document-cloudant /atg_tokida/handson-read-document,/atg_tokida/Bluemix_handson-cloudant_Credentials-1/read-document
ok: created action handson-read-document-cloudant
動作の確認
Cloudant側に文書を作成して実際に内容を読み込んで見たいと思います。準備で用意したCloudantのコンソールから新規の文書を作成します。以下のメニューを表示し「New Doc」を選択します。
文書を編集して「Create Document」を選択します。以下の_id
の値は変えずに、text
を追加して下さい。
{
"_id": "1627833a7b890131d3e32cedb4a25087",
"text": "this is test message."
}
さあ実行してみましょう
$ wsk action invoke -b -r -p id 1627833a7b890131d3e32cedb4a25087 /atg_tokida/handson-read-document-cloudant
{
"_id": "1627833a7b890131d3e32cedb4a25087",
"_rev": "1-84ab21d2a6d1b3cd6c5fd68d635d797f",
"text": "this is test message."
}
文章が取得できていることがわかりました。
Actionを更に拡張してSlackに投稿する
今度はSlackパッケージをbindコマンドを利用してBindしてみたいと思います。 以下のパラメータの urlは準備で作成したSlack のWebHockのURLとなります。
wsk package bind /whisk.system/slack handson-slack-bind --param url "https://hooks.slack.com/services/..." --param username openwhisk --param channel "#times_tokida"
Slackパッケージの中のpost actionを利用します。先ほど作成したactionを更新して更に後ろにつなげていきます。
$ wsk action update --sequence /atg_tokida/handson-read-document-cloudant /atg_tokida/handson-read-document,/atg_tokida/Bluemix_handson-cloudant_Credentials-1/read-document,/atg_tokida/handson-slack-bind/post
ok: updated action handson-read-document-cloudant
動作の確認
これで実行をおこなうとSlackに投稿されることがわかります。
$ wsk action invoke -b -r -p id 1627833a7b890131d3e32cedb4a25087 /atg_tokida/handson-read-document-cloudant
Cloudantに文章が作成されたら自動で動くように設定する
自動で処理を動かすために cloudantパッケージの中の change Feedを利用します。これはFeedと呼ばれる特殊なactionでいわゆる「イベント駆動」を実現する仕組みになります。
- name: handson-trigger
- dbname: handson-openwhisk-db
$ wsk trigger create handson-trigger --feed /atg_tokida/Bluemix_handson-cloudant_Credentials-1/changes --param dbname handson-openwhisk-db
ok: invoked /atg_tokida/Bluemix_handson-cloudant_Credentials-1/changes with id 7d9a68aab0d44cbc91f2a83561a97d1d
{
"namespace": "atg_tokida",
"name": "changes",
"version": "0.0.101",
"subject": "hideaki_tokida@niandc.co.jp",
"activationId": "7d9a68aab0d44cbc91f2a83561a97d1d",
"start": 1485105042810,
"end": 1485105043014,
"duration": 204,
"response": {
"status": "success",
"statusCode": 0,
"success": true,
"result": {}
},
"logs": [],
"annotations": [
{
"key": "limits",
"value": {
"logs": 10,
"memory": 256,
"timeout": 90000
}
},
{
"key": "path",
"value": "whisk.system/cloudant/changes"
}
],
"publish": false
}
ok: created trigger handson-trigger
次にこのTriggerと先ほど作成したactionを紐付けます。このTriggerとActionを紐付けることを「Rule」といいます。次のコマンドで rulesを作成します。
$ wsk rule create /atg_tokida/handson-rule handson-trigger /atg_tokida/handson-read-document-cloudant
ok: created rule handson-rule
$ wsk rule get /atg_tokida/handson-rule
ok: got rule handson-rule
{
"namespace": "atg_tokida",
"name": "handson-rule",
"version": "0.0.1",
"status": "active",
"trigger": {
"name": "handson-trigger",
"path": "atg_tokida"
},
"action": {
"name": "handson-read-document-cloudant",
"path": "atg_tokida"
},
"publish": false
}
動作の確認
最後の確認です。Cloudantのコンソールから新規の文章を作成してみます。
結果をSlackの画面で確認します。
このように表示されていれば成功です。
もう少し詳しく処理をみてみるためには activationの機能を利用します。
$ wsk activation list
activations
85812029a8ff4ee088f621cd4dfba293 post
0812924f696b43bbaf5b273655bb8d26 read-document
fa71e6768fd346adb2d8254e9e8e35cf handson-read-document
542e7134141a49dda4e13bce923f815a handson-read-document-cloudant
a5ed3b8c586b43999b0cb55b68db833f handson-trigger
c99d8412122f479ba20bbe53e06c6dee handson-rule
このように処理が順次行われているのが確認できます。具体的な内容を確認することも可能です。
$ wsk activation get fa71e6768fd346adb2d8254e9e8e35cf
ok: got activation fa71e6768fd346adb2d8254e9e8e35cf
{
"namespace": "atg_tokida",
"name": "handson-read-document",
"version": "0.0.2",
"subject": "hideaki_tokida@niandc.co.jp",
"activationId": "fa71e6768fd346adb2d8254e9e8e35cf",
"cause": "542e7134141a49dda4e13bce923f815a",
"start": 1485105640314,
"end": 1485105640317,
"duration": 3,
"response": {
"status": "success",
"statusCode": 0,
"success": true,
"result": {
"dbname": "handson-openwhisk-db",
"docid": "f5ff880478c80c67ef5c6a1b781eba6f"
}
},
"logs": [],
"annotations": [
{
"key": "limits",
"value": {
"logs": 10,
"memory": 256,
"timeout": 60000
}
},
{
"key": "path",
"value": "atg_tokida/handson-read-document"
},
{
"key": "causedBy",
"value": "sequence"
}
],
"publish": false
}
課題
課題(1)
- 今回の処理を全てGUIで実装してみて下さい。
課題(2)
OpenWhiskは、Function as a Serviceです。単体で完結するだけでなく外部から呼び出すことで利用の範囲が広がります。
- OpenWhiskで作成したActionを、Node-REDから呼び出してみましょう
- API Connect経由で、OpenWhiskのAPIを保護/公開するにはどのようにすればよいでしょうか
- OpenWhisで作成したActionを他のユーザと「共有」してみましょう