はじめに
前回はIRISのインターオペラビリティ機能を紹介しました。今回はその続きを説明し、いよいよアプリケーションを完成させます。
具体的には、
- ビジネス・プロセスの作成
- プロダクション構成
の作成について説明します。
最後に、OpenAPIで書かれた仕様に基づきRESTサーバをIRISに構築し、REST APIを使ってアクセスする方法についても解説します。
それでは開発を始めましょう。今回もVisual Studio Codeを使用して開発を行います。準備として、前回の内容を反映したコンテナを起動しておいてください。そのコンテナがない方は、前々回、前回の記事の内容を実施してください。
今回説明するクラスは、DriveDemoディレクトリのIRIS-MQTT/projects/srcs/iris以下にあります。説明を読みながら適宜利用してください。なお、ソースファイルなど一式をまだダウンロードしていない方は、GitHubからpullしてください。
ビジネス・プロセス
ビジネス・プロセスとは、他のコンポーネントからメッセージを受け取り、定められた業務フローを実行するコンポーネントです。ESB(Enterprise Service Bus)と呼ばれるアーキテクチャでは、ビジネス・プロセスの定義・自動実行をオーケストレーションと呼びますが、IRISのビジネス・プロセスも同様の機能を提供します。
/DriveDemo/IRIS-MQTT/projects/srcs/iris/DriveDemo/Processディレクトリに、CheckDriveProcess.clsがあるので、Visual Studio Codeのワークスペースに読み込んでください。
コードを次に示します。
Class DriveDemo.Process.CheckDriveProcess Extends Ens.BusinessProcessBPL { /// BPL Definition XData BPL [ XMLNamespace = "http://www.intersystems.com/bpl" ] { <process language='objectscript' request='DriveDemo.Request.CheckDriveRequest' response='DriveDemo.Response.CheckDriveResponse' height='2000' width='2000' > <context> <property name='drivingstatus' type='%String' instantiate='0' > <parameters> <parameter name='MAXLEN' value='2500' /> </parameters> </property> </context> <sequence xend='200' yend='700' > <call name='CheckDrivingBehavior' target='CheckDriveOperation' async='0' xpos='200' ypos='250' > <request type='DriveDemo.Request.CheckDriveRequest' > <assign property="callrequest" value="request" action="set" /> </request> <response type='DriveDemo.Response.CheckDriveResponse' > <assign property="context.drivingstatus" value="callresponse.MessageText" action="set" /> <assign property="response" value="callresponse" action="set" /> </response> </call> <if name='EventHappened?' condition='response.hasEvent = 1' xpos='200' ypos='350' xend='200' yend='600' > <true> <call name='NotifyEvent' target='MQTTOut' async='1' xpos='335' ypos='500' > <request type='Ens.StringContainer' > <assign property="callrequest.StringValue" value="response.MessageText" action="set" /> </request> <response type='Ens.Response' /> </call> </true> </if> </sequence> </process> } }
宣言部のExtends句で Ens.BusinessProcessBPLを継承しています。これは、後ほど説明するBPLエディタで図として表示可能なビジネス・プロセスのスーパークラスです。
前回紹介したデータ変換と同様、XDataブロックにXML形式でビジネス・プロセスの定義が書かれています。このXMLの形式は、ワークフローを記述する標準であるBPMN(Business Process Model & Notation)などを基にしてInterSystemsが開発したものです。
通常は、このXMLを直接編集するのではなく、IRIS(Windows版)に付属するIDE(Studio)を使ってビジュアルに編集します。ここでは、管理ポータルを使って、視覚的に表現されたビジネス・プロセスを確認しましょう。上に示したCheckDriveProcess.clsをコンパイルしておいてください。
次のURLで管理ポータルを立ち上げます。
http://localhost:52003/csp/sys/UtilHome.csp
そして、[インターオペラビリティ]→[構築]→[ビジネス・プロセス]を選択します。そうすると、次の図のような画面が表示されるので、「開く」ボタンを押し、[DriveDemo]→[Process]→[CheckDriveProcess]を選びます。
そうすると、次のようなワークフローが表示されます。
先ほどのXML形式のビジネス・プロセスが、視覚的に表示されているのが分かります。フローを見てみると、
- 運転状態のチェック
- イベントが発生していたら通知
という簡単な流れを表していることが分かります。
ワークフローの最初の処理である「運転状態のチェック」について詳細を見ていきましょう。この処理は<call>と表示されています。<call>とは、プロダクション中の他のコンポーネント(ビジネス・プロセスまたはビジネス・オペレーション)を呼び出す機能を表しています。
次の図のように、ワークフローの一番上の箱、“CheckDrivingBehavior”をクリックします。
そうすると、箱にフォーカスが当たり、右側のパネルにCheckDrivingBehaviorについての設定項目が表示されます。ここで、いくつか重要なものを説明します。
まず、ターゲットと書かれた項目に”CheckDriveOperation”と指定しています。これは、この<call>がCheckDriveOperation(ビジネス・オペレーション)を呼び出すものであることを指示しています。このビジネス・オペレーションの実体は、前回の連載で定義したものです。
その下のリクエストと書かれた項目は、呼び出し時にビジネス・オペレーションへ送信するリクエスト・メッセージについて設定します。「要求メッセージ・クラス」にDriveDemo.Request.CheckDriveRequestを指定しています。このクラスも、前回の連載で定義したものです。
さらにその下には、要求アクション設定、そして「リクエスト・ビルダ」ボタンがあります。これらは、ビジネス・オペレーションを呼び出すときに送信するリクエスト・メッセージをどのように生成するかを定義するものです。「リクエスト・ビルダ」ボタンを押すと、次のような画面が表示されます。
ご覧のとおり、前回の連載で説明したデータ変換と同じような画面は表示されます。この画面で、ビジネス・プロセスが受け取ったリクエスト・メッセージ(左側)からビジネス・オペレーションへ送信するリクエスト・メッセージ(右側)への変換を定義しています。
プロダクション構成
いよいよ最後の手順です。今まで作ったコンポーネントをプロダクションに組み込んでいきます。管理ポータルで、[Interoperability]→[構成]→[プロダクション]を選んでください(次図)。
ビジネス・オペレーションの追加
ビジネス・オペレーションをプロダクションに追加します。上の図の赤で囲った部分、”+”マークをクリックしてください。
そうすると次の図のような画面が表示されるので、オペレーションクラス名には”DriveDemo.Operation.CarUpdateOperation”、オペレーション名に”CarOperation”と入力、有効にチェックを入れて「OK」を押します。
次の図のように、プロダクションにビジネス・オペレーション”CarOperation”が追加されました。
同様の操作を、DriveDemo.Operation.CheckDriveOperationに対しても行ってください。
さらに、発生したイベントをMQTT BrokerにPublishするビジネス・オペレーションも追加します。このオペレーションは、連載第3回で紹介した、Javaビジネス・ホストです。
管理ポータルの[Interoperability]→[構築]→[Javaビジネス・ホスト]を選択します。次の図のように、Javaビジネス・ホストの生成画面が表示されるので、画面左側、アクティブなプロダクションで”DriveDemo.Production”を選択します。プロダクションを起動するダイアログが出たらOKを押してください。
そして、画面中央の設定で、Jarのファイルパスに”/projects/srcs/java/lib/IRIS-MQTT-Client.jar”を選択、Javaのクラス名に”com.intersystems.drivedemo.MqttBO(ビジネス・オペレーション)”を選択、デフォルト認証情報に”SuperUser”を入力し、「生成」ボタンを押します。
次に、プロダクション構成の画面に戻って、ビジネス・オペレーションの追加ボタン”+”を押し、次の図のように、オペレーションクラスに”JBH.Com.Intersystems.Drivedemo.MqttBO”を選択、オペレーション名に”MQTTOut”と入力し、有効にするをチェックして「OK」を押します。
プロダクション構成の画面に戻り、ビジネス・オペレーション”MQTTOut”を選択します。そうすると、画面右側に設定項目が表示されます。そこで、「追加の設定」を展開し、
- MQTTBroker: tcp://mqttbroker:1883
- MQTTClientName: IRISClientOut
- MQTTTopicRoot: DriveDemo/Event
- LogFile: /projects/logs/MQTTBO.log
と各項目に入力してください(次図)。
最後にプロダクションを更新します。「更新」ボタンを押してみてください(うまくいかない場合は、「停止」→「開始」の順にボタンを押して、プロダクションを再起動します)。
ビジネス・プロセスの追加
次に、ビジネス・プロセスを追加しましょう。追加するのは、今回の連載の初めに定義したCheckDriveProcessです。
管理ポータルのプロダクション構成の画面から、ビジネス・プロセス追加の”+”マークをクリックします。そうすると次の図のような画面が表示されるので、ビジネス・プロセス・クラスに”DriveDemo.Process.DriveCheckProcess”を選択、ビジネス・プロセス名に”DriveCheckProcess”と入力、有効にチェックを入れ、「OK」ボタンを押します。
以上の作業で、プロダクション全体は次の図のようになります。管理ポータルのプロダクション構成を確認してください。
ビジネス・ルールの設定
プロダクション構成の仕上げに、ビジネス・プロセス”RoutingProcess”が参照するビジネス・ルールの設定を行います。
RoutingProcessは第3回の連載でプロダクションに追加しましたが、参照するルールは自動生成したものを暫定的に設定しました。ここで、前回作成したビジネス・ルールを参照するように変更します。
管理ポータルのプロダクション構成の画面で、”RoutingProcess”をクリックします。そうすると、右側のパネルに設定項目が表示されます。そこで、[基本の設定]→[ビジネス・ルール名]に”DriveDemo.DemoProcessRoutingRule”を選択し、「適用」ボタンを押します(次図)。
以上でプロダクションが完成しました。
REST APIの作成(1)
この連載の最後に、IRISが保持する車の最新情報を取得するためのREST APIを作成します。
IRISでREST APIを作成する方法にはいくつかありますが、今回は、OpenAPI 2.0を利用する方法を紹介します。実際に試す方は、REST APIを呼び出せるツールを用意してください。この連載では、Postmanを使用します。
REST APIの生成と実装
OpenAPIは、REST APIのインターフェースを記述するための仕様で、OpenAPI Initiativeにより管理されています。IRISは、OpenAPI 2.0に準拠した仕様をもとに、REST APIを作成することができます。
次に示すのは、OpenAPIで記述されたインターフェース定義の一部です。DriveDemo/IRIS-MQTT/projects/RestAPI/spec.jsonというJSONファイルがあるので確認してください。
{ "swagger":"2.0", "info":{ "version":"1.0.0", "title":"Drive Demo", "description":"Drive Demo: REST APIの定義", "termsOfService":"http://swagger.io/terms/", "contact":{ "name":"InterSystems Japan" }, "license":{ "name":"MIT" } }, "basePath":"/csp/DriveDemo", "schemes":[ "http" ], "consumes":[ "application/json" ], "produces":[ "application/json" ], "paths":{ "/cars":{ "get":{ "description":"すべての車の情報を返す", "operationId":"getAllCars", "produces":[ "application/json" ], "responses":{ "200":{ "description":"車のリスト", "schema":{ "type":"array", "items":{ "$ref":"#/definitions/Car" } } } } } } }, "definitions":{ "Car":{ "type":"object", "required":[ "carid", "relativetm", "longitude", "latitude", "azimuth", "speed", "enginerpm", "accelpos", "brakesw" ], "properties":{ "carid":{ "type":"string" }, …後略… }
いくつか重要な項目を説明します。
- “basePath” : APIのルートとなるURLのパス名です。IRISでは、後に説明するようにWebアプリケーション名としてこのパス名を使用します。
- “paths” : インターフェースに含まれるAPIそれぞれの相対パスです。ここでは、/carsというAPIがGETメソッドを受け取るよう定義されています。また、”operationId”には、IRISが生成するメソッドの名前を指定します。
ではPostmanでREST APIの生成を行います。Postmanを立ち上げます。次の図のように、リクエストの画面に設定を行います。
- メソッドにはPOSTを選択します。
- URLはhttp://localhost:52003/api/mgmnt/v2/drive/DriveDemoを指定します。ここで/api/mgmnt/v2がIRISのAPI作成機能のURLで、/driveはネームスペース、/DriveDemoはアプリケーション名を示します。
- Bodyを選択し、上で示したJSONファイルの内容を貼り付けます。また、”raw”と”JSON”を選択します。
- 上の図のように、Authorizationタブを開き、TYPEには”Basic Auth”、ユーザ名・パスワードには、SuperUser/driveuserと指定します。
- 上の図のとおり、Headersタブを開き、”Content-Type”に” application/json; charset=utf-8”を指定します。
次に”Send”ボタンを押します。そうすると、IRISにリクエストが送信され、REST APIの生成に成功すれば、次の図のような応答が得られます。
それではVisual Studio Codeに戻って、生成されたクラスを確認してみましょう。生成されたのは、DriveDemo.implとDriveDemo.specです。次の図のように、Visual Studio Codeの左側メニューからInterSystems のロゴをクリックし、”projects”→”Classes”から2つのクラスにアクセスすることができます。
Postmanから生成したREST APIの実装を行うには、DriveDemo.implクラスを編集します。
DriveDemo.implクラスを開くと、IRISが生成したテンプレートが書かれており、getAllCarsメソッドの定義があります。getAllCarsメソッドの中身に次のようなコードを記述しコンパイルします。
ClassMethod getAllCars() As %DynamicObject { // SQLで車の最新情報を取得し、DynamicObjectを生成する Set tArr = [] Set tRS = ##class(%SQL.Statement).%ExecDirect(,"SELECT CarId, RelativeTm, Longitude, Latitude, Azimuth, Speed, EngineRPM, AccelPos, BrakeSW, aX, aY, aZ FROM DriveDemo_Data.CarLatest order by CarId") While tRS.%Next() { Do tArr.%Push({ "carid": (tRS.%Get("CarId")), "relativetm": (tRS.%Get("RelativeTm")), "longitude": (tRS.%Get("Longitude")), "latitude": (tRS.%Get("Latitude")), "azimuth": (tRS.%Get("Azimuth")), "speed": (tRS.%Get("Speed")), "enginerpm": (tRS.%Get("EngineRPM")), "accelpos": (tRS.%Get("AccelPos")), "brakesw": (tRS.%Get("BrakeSW")), "aX": (tRS.%Get("aX")), "aY": (tRS.%Get("aY")), "aZ": (tRS.%Get("aZ")) }) } Do ..%SetStatusCode(200) Quit tArr.%ToJSON() }
このメソッドでは、SELECT文でDriveDemo_Data.CarLatestを検索し、得られた結果をJSON形式に変換して返しています。
もう1か所編集を行います。DriveDemo.specクラスを開き、
Parameter HandleCorsRequest = 1;
のようにHandleCorsRequestパラメータに1をセットします。これは、CORS(Cross-Origin Resource Sharing)をオンにするものです。CORSとは、簡単にいうと、Webページをサービスしているサーバと異なるサーバに対してRESTリクエストを送信する機能のことです。
REST APIの作成(2)
REST APIの設定
以上で定義・生成・実装したREST APIを使用するために、いくつか設定を行う必要があります。管理ポータルで、「システム管理」→「セキュリティ」→「アプリケーション」→「ウェブ・アプリケーション」をクリックし、次の画面のように「新しいウェブ・アプリケーションを作成」を押します。
ウェブ・アプリケーション作成画面では、以下のとおり設定します(次図)。
- アプリケーション名: “/csp/DriveDemo”
- ネームスペース: “DRIVE”
- 有効:”REST”
- ディスパッチ・クラス: “DriveDemo.disp”
- 許可された認証方法: “認証なし”、”パスワード”
そして、「保存」ボタンを押します。
次に、セキュリティの設定を行います。管理ポータルの「システム管理」→「セキュリティ」→「ユーザ」をクリックします。そして、次の画面で”UnknownUser”をクリックします。
表示された画面で「ロール」をクリックし、「利用可能」の選択肢から”%DB_%DEFAULT”を選び、右矢印をおして「選択済み」へ移動させ、「付与する」ボタンを押します(次図)。
次に、以下2つの図のとおり、「SQLテーブル」タブを選び、「テーブルを追加…」ボタンを押し、次の画面で、スキーマを選択: “DriveDemo_Data”、利用可能の一覧から”CarLatest”を右の選択済みに移動、「適用」ボタンを押します。
以上ですべての設定が完了しました。Postmanを使って、http://localhost:52003/csp/DriveDemo/carsにGETメソッドを送信すると、次の図のようにJSON形式で車の最新情報が返されることを確認できます。
これをもって、連載第2回でデモしたアプリケーションがすべて完成しました。
まとめ
この連載では、6回に渡ってInterSystems IRIS Data Platformの設計思想、開発手法についてご紹介してきました。題材として使用したのは、車載器から発生するデータをMQTTプロトコルでリアルタイムに受信して、データを変換・加工、保存し、運転状況に異常がないかチェックするアプリケーションでした。
「データは21世紀のエンジンである」と言われる時代において、IoTに代表されるような大量かつ多様な形式のデータを、リアルタイムに処理するニーズが高まっています。そういった処理には、多様なデータ形式を標準的なものに変換したり、複数の発生源からのデータを突合したりして、重複や欠損をなくすようなものが含まれます。
連載で紹介したIRISのインターオペラビリティ機能は、発生源からのデータをあらかじめ定められたルールやフローに基づいて処理するものです。IRISはオブジェクト指向のサポートにより、ルールやフローなどのコンポーネントをシンプルに開発することを可能にします。また、高速なデータベースによってメッセージの保存、トレースが容易であり、効率的なシステム運用を行うことができます。
連載では、大変多くの設定作業を紹介しました。もしかしたら、面倒に感じられた部分もあるかもしれません。しかし、出来上がったアプリケーションのコードの量は驚くほど少ないと思います。いったんIRISの開発手法をマスターすれば、シンプルなアーキテクチャーで高性能なアプリケーションを高い生産性で作ることができます。末尾のリンクでご案内している情報にアクセスして、さらにIRISを体験してみてください。
IRISに保存したデータを機械学習にかけたりして活用する手法については、今回の連載では紹介できませんでした。InterSystemsでは、機械学習やAIの活用をシンプルにする取り組みも行っています(参考:Developers Summit 2020のセッションレポート)。いずれ、CodeZineでそれらの機能についてご紹介できるよう計画したいと思います。ご期待ください。
連載を最後までお読みいただきまして、ありがとうございました。
参考
インターシステムズでは、開発者の皆様にIRISを知っていただくために、いろいろな機能を紹介する短い動画を作成しています(日本語字幕付き)。
また、TRY-IRISをご利用いただくと、QuickStartの一部コースを専用のWebIDE上ですぐにお試しいただけます。あわせてご検討ください。
インターオペラビリティ機能は以下のURLで説明されています。ぜひご覧ください。