13 EDQでのスクリプト化グローバルWebサービスの使用

EDQ 12.2.1.4.4では、グローバルWebサービスの制限されたサポートが復活しています。このドキュメントの対象読者は、EDQアプリケーションのインストールおよび管理を担当するシステム管理者です。

この章の内容は次のとおりです。

13.1 グローバルWebサービスおよびEDQの概要

EDQ 12.2.1.4.0以前では、ローカルWebサービス・ディレクトリにjarとしてインストールされたグローバルSOAP Webサービスがサポートされていました。グローバルWebサービスのサポートはEDQ 12.2.1.4.1で削除されました。

EDQ 12.2.1.4.4以降では、読取りおよびパブリッシュにグローバルWebサービスを使用するように、リアルタイム・プロバイダ・バケットおよびコンシューマ・バケットを構成できます。これらのWebサービス・バケット・ファイルは、スクリプトを使用して着信テキスト・ペイロードをデコードし、発信テキスト結果を生成します。サポートされているペイロード形式は、JSON (application/json)、XML (text/xml)およびプレーン・テキスト(text/plain)です。

ノート:

SOAPはサポートされていません。

13.2 Webサービス・リクエストの読取りおよび書込みを行うためのEDQの構成

EDQとのWebサービス・インタフェースは、次のものを定義するXMLインタフェース・ファイルを使用して構成します:

  • WebサービスのURLパス
  • メッセージ・ペイロードをEDQプロセスで認識される形式にデコードする方法(メッセージ・プロバイダの場合、EDQがメッセージを読み取る)、またはメッセージを外部プロセスで予測される形式に変換する方法(メッセージ・コンシューマの場合、EDQがメッセージを書き込む)。

XMLファイルは、次のパスのEDQローカル・ホーム・ディレクトリ(以前の構成ディレクトリ)にあります。

  • buckets/realtime/providers (EDQに入力するインタフェース)
  • buckets/realtime/consumers (EDQから出力するインタフェース)

XMLファイルが構成されると、メッセージ・プロバイダ・インタフェースがEDQのリーダー・プロセッサで使用可能になり、データ・インタフェースをプロセスへの「入力」としてマップできます。また、メッセージ・コンシューマ・インタフェースはライター・プロセッサで使用可能になり、データ・インタフェースからプロセスの「出力」としてマップできます。

13.3 インタフェース・ファイルの定義

EDQのインタフェース・ファイルは、メッセージ・フレームワークを定義するrealtimedata要素で構成されます。結果を返すWebサービスは、プロバイダ・バケットおよびコンシューマ・バケットによって定義されます。両方の構成を同期としてマークする必要があります。Webサービスでは、次を使用します:

<?xml version="1.0" encoding="UTF-8"?>
 
<realtimedata messenger="ws" synchronous="true">
    ...
</realtimedata>

realtimedata要素には、3つのサブセクションがあります:

  • <attributes>セクション: EDQで認識できるインタフェースの形状を定義します
  • <messengerconfig>セクション: Webサービス・エンドポイントに接続する方法を定義します。
  • メッセージ・フォーマット・セクション: (たとえば、XMLから)メッセージのコンテンツをEDQが読み込める属性データに抽出する方法(インバウンド・インタフェースの場合)、またはEDQからメッセージ・データに(たとえば、XMLに)属性データを変換する方法を定義します。プロバイダ・インタフェースの場合、要素は<incoming>で、コンシューマ・インタフェースの場合、要素は<outgoing>です。

13.3.1 <attributes>セクションの理解

< attribute >セクションでは、インタフェースの形状を定義します。これは、リーダーまたはライターを構成するときにEDQで使用できる属性から構成されます。

プロバイダ・スクリプトは着信ペイロードからrecordオブジェクトを生成し、コンシューマ・スクリプトはレコード・コンテンツを発信ペイロードに変換します。プロバイダ・バケット・スクリプトで、新しいRecord()またはnewRecord()を使用してレコードを作成します。2番目の形式は、Groovyスクリプトで使用する必要があります。その後、次のような割当てで属性を設定します:

rec.id = 23
rec.name = "John Smith"

レコード・オブジェクトには、バケットの属性セクションで定義された属性が含まれます。たとえば、インタフェース・ファイルの先頭部分の次の抜粋では、バケットの属性が定義されます。これにより、idnameおよびemail属性を含むレコード・オブジェクトが生成されます:

<?xml version="1.0" encoding="UTF-8"?>
<realtimedata messenger="ws">
<attributes>
  <attribute name="id"    id="1" type="number"/>
  <attribute name="name"  id="2" type="string"/>
  <attribute name="email" id="3" type="string"/>
</attributes> 

[file continues]...

EDQでは、次のすべての標準属性タイプがサポートされます。

  • 文字列
  • 数値
  • 日付
  • stringarray
  • numberarray
  • datearray

13.3.2 <messengerconfig>セクションの理解

messengerconfigセクションには、パス・プロパティを含める必要があります。値は、Webサービスのエンドポイントを形成するためにhttp://server/edq/restws/に追加されます。

パスには、文字、数字およびアンダースコア(_)文字を含めることができます。

13.3.3 <incoming>または<outgoing>セクションの理解

<incoming> or <outgoing>セクションでは、メッセージ・メタデータおよび値をEDQ属性との間で変換する方法を定義します。これは、次の2つのサブセクションで構成されます:

プロバイダ・バケットとコンシューマ・バケットは、incoming要素とoutgoing要素にkey属性を追加することでリンクされます:

<incoming key="addup1">
<outgoing key="addup1">

単一のサービスのプロバイダWebサービス・バケットとコンシューマWebサービス・バケットで同じキー値を使用する必要があります。サービスごとに異なるキー値を使用する必要があります。

13.3.3.1 <messageheaders>セクションの理解

<messageheaders>セクションはオプションです。これは、レコード値の外部にあるデータをEDQ属性との間で変換する方法を定義します。このセクションの形式は次のとおりです:

<messageheaders>
   <header name=”headername” attribute=”attributename”/>
  …
</messageheaders>
13.3.3.2 <messagebody>セクションの理解

このセクションでは、JavaScriptを使用して、EDQがインバウンド・インタフェースに使用できる属性にメッセージ・ペイロードを解析し、アウトバウンド・インタフェースのために逆操作(EDQ属性データをメッセージ・ペイロード・データに変換)を実行します。‘extract’という名前の関数は、XMLからインバウンド・インタフェースの属性データへのデータの抽出に使用され、‘build’という名前の関数は、属性データからXMLデータを構築するために使用されます。

プロバイダ定義

プロバイダ・バケットXMLファイルは、スクリプト・デコーダを使用して入力ペイロードから属性を作成します:

<messagebody>
  <script content="...">
   <![CDATA[
     function extract(payload, type, mtags, env) {
       ...
     }
   ]]>
  </script>
</messagebody>

content属性は、プロバイダがサポートする入力タイプのカンマ区切りリストです:

  • json: コンテンツ・タイプがapplication/jsonのJSONテキスト。
  • dom: コンテンツ・タイプがtext/xmlのXMLテキスト。XMLは、Webサービス・フレームワークによってDOMに解析されます。スクリプトでDOMをデコードするには、new XML(payload)を使用します。
  • text: コンテンツ・タイプがtext/plainのプレーン・テキスト。

スクリプトでサポートされていないコンテンツ・タイプによるWebサービス・コールは、415エラーで失敗します。使用される実際のタイプは、env.contenttype;にあります。スクリプトで複数のコンテンツ・タイプがサポートされている場合は、これを使用してペイロードの解析方法を決定できます。

詳細は、プロバイダ・バケットXMLファイルの例を示したを参照してください。

コンシューマ定義

コンシューマ・バケットXMLファイルは、スクリプト・エンコーダを使用して入力属性から結果テキストを作成します:

<messagebody>
  <script content="...">
   <![CDATA[
     function build(recs, mtags, ctype) {
       ...
     }
   ]]>
  </script>
</messagebody>

content属性は、コンシューマがサポートする出力タイプのカンマ区切りリストです:

  • recsは、レコード・オブジェクトの配列です。
  • ctypeは、着信リクエストのコンテンツ・タイプ(json、domまたはtext)です。サービスで複数のコンテンツ・タイプが受け入れられる場合は、これを使用して正しい形式で出力を作成します。

リクエストに複数のレコードを含めることができる場合は、multirecord="true"を設定します:

<script multirecord="true"> 

詳細は、コンシューマ・バケットXMLファイルの例を示したを参照してください。

13.4

これは、addupという単純なグローバルWebサービスの例で、2つの数値を受け入れて合計を生成します。サポートされる入力形式は、JSON、XMLおよびプレーン・テキストです。サービスのパスはaddupで、Webサービス・エンドポイントは次のとおりです:

http://server:port/edq/restws/addup

次の表は、このサービスの例に基づく入力形式と出力形式の動作方法を示しています。

サポートされる形式 入力例 出力例

JSON

{ "n1" : 100,
  "n2" : 235
}
{
  "inputs": [
    100,
    235
  ],
  "sum": 335
}

XML

<request>
  <n1>100</n1>
  <n2>223</n2>
</request>
<response>
  <inputs>
    <v>100</v>
    <v>223</v>
  </inputs>
  <sum>323</sum>
</response>

プレーン・テキスト

234,129 234 + 129 = 363

例1 – プロバイダ・ファイル

次のXMLは、プロバイダ・バケットXMLファイルの例です:

<?xml version="1.0" encoding="UTF-8"?>
<realtimedata messenger="ws" synchronous="true">

  <!-- ================================================= -->
  <!-- The attributes which are created by this provider -->
  <!-- ================================================= -->

  <attributes>
    <attribute name="n1" id="1" type="number"/>
    <attribute name="n2" id="2" type="number"/>
  </attributes>

  <!-- ============================= -->
  <!-- The web service configuration -->
  <!-- ============================= -->

  <messengerconfig>
    path = addup
  </messengerconfig>

  <!-- ==================================== -->
  <!-- The script which unpacks the payload -->
  <!-- ==================================== -->

  <incoming key="addup1">
    <messagebody>
      <script content="json,text,dom">
       <![CDATA[
         function extract(str, type, mtags, env) {
           if (env.contenttype == "json") {
             var x = JSON.parse(str)
             var r = new Record();

             r.n1 = x.n1
             r.n2 = x.n2

             return [r];
           } else if (env.contenttype == "dom") {
             var x = new XML(str)
             var r = new Record();

             r.n1 = parseInt(x.n1)
             r.n2 = parseInt(x.n2)

             return [r];
           } else {
             var a = str.split(",")
             var r = new Record();

             r.n1 = parseInt(a[0])
             r.n2 = parseInt(a[1])

             return [r];
           }
         }
       ]]>
      </script>
    </messagebody>
  </incoming>

</realtimedata>

例2 – コンシューマ・ファイル

次のXMLは、コンシューマ・バケットXMLファイルの例です:

<?xml version="1.0" encoding="UTF-8"?>
<realtimedata messenger="ws" synchronous="true">

  <!-- =================================================== -->
  <!-- The attributes which are accepted by this consumer -->
  <!-- ================================================== -->

  <attributes>
    <attribute name="n1"  type="number"/>
    <attribute name="n2"  type="number"/>
    <attribute name="sum" type="number"/>
  </attributes>

  <!-- ============================= -->
  <!-- The web service configuration -->
  <!-- ============================= -->

  <messengerconfig>
    path = addup
  </messengerconfig>

  <!-- =================================== -->
  <!-- The script which creates the output -->
  <!-- =================================== -->

  <outgoing key="addup1">
    <messagebody>
      <script multirecord="true">
        <![CDATA[
          function build(recs, mtags, ctype) {
            var rec = recs[0]

            if (ctype == 'json') {
              return JSON.stringify({ inputs: [rec.n1, rec.n2], sum: rec.sum }, null, 2)
            } else if (ctype == "dom") {
              return  <response><inputs><v>{rec.n1}</v><v>{rec.n2}</v></inputs><sum>{rec.sum}</sum></response>.toXMLString()
            } else {
              return rec.n1 + " + " + rec.n2 + " = " + rec.sum
            }
          }
        ]]>
      </script>
    </messagebody>
  </outgoing>

</realtimedata>