SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

InterSystems IRISでシンプルに開発するIoTアプリケーション(AD)

IRISのインターオペラビリティ機能を使いこなそう(後編)~OpenAPIを利用したRESTサーバの構築

InterSystems IRISでシンプルに開発するIoTアプリケーション 第6回

  • このエントリーをはてなブックマークに追加

 この連載では、InterSystems IRIS Data Platform(以下IRIS)を使って車載器から発生するデータを扱うIoTアプリケーションの構築方法を紹介しています。これまでの連載をまだご覧いただいていない方は、ぜひこの機会にお試しください。

  • このエントリーをはてなブックマークに追加

はじめに

 前回は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”をクリックします。

<call>説明
説明

 そうすると、箱にフォーカスが当たり、右側のパネルにCheckDrivingBehaviorについての設定項目が表示されます。ここで、いくつか重要なものを説明します。

 まず、ターゲットと書かれた項目に”CheckDriveOperation”と指定しています。これは、この<call>がCheckDriveOperation(ビジネス・オペレーション)を呼び出すものであることを指示しています。このビジネス・オペレーションの実体は、前回の連載で定義したものです。

 その下のリクエストと書かれた項目は、呼び出し時にビジネス・オペレーションへ送信するリクエスト・メッセージについて設定します。「要求メッセージ・クラス」にDriveDemo.Request.CheckDriveRequestを指定しています。このクラスも、前回の連載で定義したものです。

 さらにその下には、要求アクション設定、そして「リクエスト・ビルダ」ボタンがあります。これらは、ビジネス・オペレーションを呼び出すときに送信するリクエスト・メッセージをどのように生成するかを定義するものです。「リクエスト・ビルダ」ボタンを押すと、次のような画面が表示されます。

リクエスト・ビルダ
リクエスト・ビルダ

 ご覧のとおり、前回の連載で説明したデータ変換と同じような画面は表示されます。この画面で、ビジネス・プロセスが受け取ったリクエスト・メッセージ(左側)からビジネス・オペレーションへ送信するリクエスト・メッセージ(右側)への変換を定義しています。

プロダクション構成

 いよいよ最後の手順です。今まで作ったコンポーネントをプロダクションに組み込んでいきます。管理ポータルで、[Interoperability]→[構成]→[プロダクション]を選んでください(次図)。

プロダクション構成
プロダクション構成

ビジネス・オペレーションの追加

 ビジネス・オペレーションをプロダクションに追加します。上の図の赤で囲った部分、”+”マークをクリックしてください。

 そうすると次の図のような画面が表示されるので、オペレーションクラス名には”DriveDemo.Operation.CarUpdateOperation”、オペレーション名に”CarOperation”と入力、有効にチェックを入れて「OK」を押します。

ビジネス・オペレーション追加
ビジネス・オペレーション追加

 次の図のように、プロダクションにビジネス・オペレーション”CarOperation”が追加されました。

プロダクション構成 CarOperation追加後
プロダクション構成 CarOperation追加後

 同様の操作を、DriveDemo.Operation.CheckDriveOperationに対しても行ってください。

 さらに、発生したイベントをMQTT BrokerにPublishするビジネス・オペレーションも追加します。このオペレーションは、連載第3回で紹介した、Javaビジネス・ホストです。

 管理ポータルの[Interoperability]→[構築]→[Javaビジネス・ホスト]を選択します。次の図のように、Javaビジネス・ホストの生成画面が表示されるので、画面左側、アクティブなプロダクションで”DriveDemo.Production”を選択します。プロダクションを起動するダイアログが出たらOKを押してください。

Javaビジネス・ホスト生成
Javaビジネス・ホスト生成

 そして、画面中央の設定で、Jarのファイルパスに”/projects/srcs/java/lib/IRIS-MQTT-Client.jar”を選択、Javaのクラス名に”com.intersystems.drivedemo.MqttBO(ビジネス・オペレーション)”を選択、デフォルト認証情報に”SuperUser”を入力し、「生成」ボタンを押します。

 次に、プロダクション構成の画面に戻って、ビジネス・オペレーションの追加ボタン”+”を押し、次の図のように、オペレーションクラスに”JBH.Com.Intersystems.Drivedemo.MqttBO”を選択、オペレーション名に”MQTTOut”と入力し、有効にするをチェックして「OK」を押します。

MQTTOutの追加
MQTTOutの追加

 プロダクション構成の画面に戻り、ビジネス・オペレーション”MQTTOut”を選択します。そうすると、画面右側に設定項目が表示されます。そこで、「追加の設定」を展開し、

  • MQTTBroker: tcp://mqttbroker:1883
  • MQTTClientName: IRISClientOut
  • MQTTTopicRoot: DriveDemo/Event
  • LogFile: /projects/logs/MQTTBO.log

と各項目に入力してください(次図)。

MQTTOutの設定
MQTTOutの設定

 最後にプロダクションを更新します。「更新」ボタンを押してみてください(うまくいかない場合は、「停止」→「開始」の順にボタンを押して、プロダクションを再起動します)。

ビジネス・プロセスの追加

 次に、ビジネス・プロセスを追加しましょう。追加するのは、今回の連載の初めに定義した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を立ち上げます。次の図のように、リクエストの画面に設定を行います。

API作成リクエスト1
API作成リクエスト1
  • メソッドにはPOSTを選択します。
  • URLはhttp://localhost:52003/api/mgmnt/v2/drive/DriveDemoを指定します。ここで/api/mgmnt/v2がIRISのAPI作成機能のURLで、/driveはネームスペース、/DriveDemoはアプリケーション名を示します。
  • Bodyを選択し、上で示したJSONファイルの内容を貼り付けます。また、”raw”と”JSON”を選択します。
API作成リクエスト2
API作成リクエスト2
  • 上の図のように、Authorizationタブを開き、TYPEには”Basic Auth”、ユーザ名・パスワードには、SuperUser/driveuserと指定します。
API作成リクエスト3
API作成リクエスト3
  • 上の図のとおり、Headersタブを開き、”Content-Type”に” application/json; charset=utf-8”を指定します。

 次に”Send”ボタンを押します。そうすると、IRISにリクエストが送信され、REST APIの生成に成功すれば、次の図のような応答が得られます。

API作成レスポンス
API作成レスポンス

 それではVisual Studio Codeに戻って、生成されたクラスを確認してみましょう。生成されたのは、DriveDemo.implとDriveDemo.specです。次の図のように、Visual Studio Codeの左側メニューからInterSystems のロゴをクリックし、”projects”→”Classes”から2つのクラスにアクセスすることができます。

DriveDemo.specクラス
DriveDemo.specクラス

 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”を右の選択済みに移動、「適用」ボタンを押します。

SQLテーブル設定1
SQLテーブル設定1
SQLテーブル設定2
SQLテーブル設定2

 以上ですべての設定が完了しました。Postmanを使って、http://localhost:52003/csp/DriveDemo/carsにGETメソッドを送信すると、次の図のようにJSON形式で車の最新情報が返されることを確認できます。

REST実行
REST実行

 これをもって、連載第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で説明されています。ぜひご覧ください。

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/12286 2020/05/26 12:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング