対象変数を使用したデータの強化

Mule 4.1 の標準サポートは 2020 年 11 月 2 日に終了しました。このバージョンの Mule は、拡張サポートが終了する 2022 年 11 月 2 日にその すべてのサポート​が終了しました。

このバージョンの Mule を使用する CloudHub には新しいアプリケーションをデプロイできなくなります。許可されるのはアプリケーションへのインプレース更新のみになります。

標準サポートが適用されている最新バージョンの Mule 4 にアップグレード​することをお勧めします。これにより、最新の修正とセキュリティ機能強化を備えたアプリケーションが実行されます。

Mule アプリケーションでフローを作成するときに、データを変数に保存して、フローのどのコンポーネントでも使用できるようにする必要のある場合があります。non-void の操作 (File Connector に対する Read 操作など) では、返すメッセージデータを変数に保存できます。Target (対象) (​target​) パラメータを指定して作成した変数を定義すると、フロー内で使用できるようになり、他の変数の場合と同じようにアクセスできます。

多くの場合は、次のパラメータを指定して変数を定義します。

  • Target (対象) (​target​): メッセージデータを格納する変数の名前。数字、文字、アンダースコアのみを使用できます。たとえば、名前にハイフンは使用できません。

  • 対象値 (​targetValue​): 対象変数に保存するデータの値。このデフォルト値はメッセージペイロード (​payload​) です。この項目は、変数が受け入れるすべての値を受け入れます。サポートされているデータ型、DataWeave の式、​payload​、​attributes​、​message​ キーワードが該当しますが、​vars​ キーワードは​対象外​です。

考慮事項

対象変数を設定すると、フローにおけるメッセージの典型的な進路が変化します。通常、操作で出力されるメッセージは、入力として受け取ったものとは異なります。

メッセージフローの標準動作

他方、操作からの変数を設定した場合は、操作によってフローの​次の​コンポーネントに、入力として受け取ったものと同じメッセージが出力されます。たとえば、フローにコンポーネント A、次に ​myMessage​ の対象値を指定したコンポーネント B、続いてコンポーネント C があるとします。 この場合、コンポーネント C は、B が A から受信したものと同じメッセージを受信します。

対象変数を使用したメッセージフロー

対象変数を設定すると、既存の変数の動作にも影響します。既存の変数は、対象変数の操作の処理が終了した後、元の値を保持します。たとえば、フローで変数 1 と 2 を設定したとします。その後の操作で変数 1 と 2 が変更され、対象変数 A も出力されます。この場合、操作の実行後に変数 1 と 2 は以前の値に戻ります。

対象変数と追加の変数を使用したメッセージフロー
1 コンポーネントによって対象変数が設定されたため、変数 1 と 2 はコンポーネントの実行後に以前の値に戻ります。

対象変数の設定例

次の例では、​readme.txt​ のペイロードを ​myVar​ に保存する Read 操作を設定します。

<file:read path="readme.txt" target="myVar" />

デフォルトでは完全なペイロードが ​myVar​ 対象変数に保存されます。ペイロードとは異なる値を保存する場合は、対象値 (​targetValue​) を指定するだけで済みます。

この例では、​myVar​ にメッセージ全体が保存されます。

<file:read path="readme.txt" target="myVar" targetValue="#[message]" />

この場合、変数 ​myVar​ にはファイルのコンテンツのほか、関連するすべてのメタデータも含まれます。

  • ファイルのコンテンツにアクセスする式: #[myVar.payload]

  • ファイルのメタデータにアクセスする式: #[myVar.attributes]

この例では、ファイルサイズのみが ​myVar​ に保存されます。

<file:read path="readme.txt" target="size" targetValue="#[attributes.size]" />

以下の各シナリオで、対象変数を使用することが考えられる数種のケースについて説明します。

シナリオ: 操作内から対象変数を設定する

Database Connector の操作 (Insert など) で返されたメッセージ全体 (ペイロードと属性) をログに記録するとします。操作の後に Set Variable コンポーネントを使用するのではなく、対象変数を操作に直接追加すればメッセージデータを取得できます。

<db:insert config-ref="dbConfig" target="result" targetValue="#[message]">
    <db:sql>INSERT INTO PLANET(POSITION, NAME, DESCRIPTION) VALUES (777, 'Pluto', :description)</db:sql>
    <db:parameter-types>
        <db:parameter-type key="description" type="CLOB"/>
    </db:parameter-types>
    <db:input-parameters>
        #[{'description' : payload}]
    </db:input-parameters>
</db:insert>
  • Insert 操作の対象変数: result

  • 対象値: Design Center の ​message​、Anypoint Studio の ​#[message]​。

そうすると、Logger から次のような結果を取得するものと思われます。

<logger level="INFO" doc:name="Logger" doc:id="8dca355c-a85c-44db-8c53-5b9c188a2431" message="Payload is: #[vars.result.payload] and attributes are: #[vars.result.attributes]"/>
  • メッセージ: Payload is: #[vars.result.payload] and attributes are: #[vars.result.attributes]

プラネットデータベースの最初のエントリの名前をログに記録するとします。対象変数は、Database Connector の Select 操作を使用して次のように定義できます。

<db:select config-ref="dbConfig" target="planetName" targetValue="#[payload[0].name]">
    <db:parameterized-query>select * from PLANET order by ID</db:parameterized-query>
</db:select>
  • Select 操作の対象変数: planetName

  • 対象値: Design Center の ​payload[0].name​、Anypoint Studio の ​#[payload[0].name]​。

そうすると、Logger から次のような結果を取得するものと思われます。

<logger level="INFO" doc:name="Logger" doc:id="8dca355c-a85c-44db-8c53-5b9c188a2431" message="#['Planet name is: ' ++ vars.planetName]"/>
  • メッセージ: 'Planet name is: ' ++ vars.planetName

シナリオ: 保存された値を操作の入力として使用する

ある惑星が発見された後に発見されたすべての惑星にアクセスしたいとします。Select 操作内に ​discoveryDate​ という、惑星の発見日を取得する対象変数を作成することが考えられます。

<db:select config-ref="dbConfig" target="discoveryDate" targetValue="#[payload[0].discoveryDate]">
    <db:sql>select discoveryDate from PLANET where name = :name</db:sql>
    <db:input-parameters>
        #[{'name' : 'pluto'}]
    </db:input-parameters>
</db:select>
  • Retrieve 操作の対象変数: discoveryDate

続いて、たとえば次のように、フローの別の操作 (Database Connector に対する Select 操作など) の入力パラメータを使用して、クエリでその変数を使用できるようにします。

<db:select config-ref="dbConfig" target="discoveryDate" targetValue="#[payload[0].discoveryDate]">
    <db:sql>select * from PLANET where discoveryDate > :discoveryDate</db:sql>
    <db:input-parameters>
        #[{'discoveryDate' : vars.discoveryDate}]
    </db:input-parameters>
</db:select>
  • Select 操作の入力パラメータの定義:

    • キー: discoveryDate

    • 値: Design Center の ​vars.discoveryDate​、Anypoint Studio の ​#[vars.discoveryDate]​。

シナリオ: 通常のメッセージフローをバイパスする

メッセージのペイロードにある多数のレコードをデータベースに挿入してから、後続の処理のためにこの同じレコードをフローの次のコンポーネントに渡すとします。Database Connector に対して Bulk Insert 操作を使用してレコードを挿入したいのですが、この操作は成功メッセージを返して現在のペイロードを置き換えてしまうため、レコードにはアクセスできなくなります。そこで、ペイロードが Bulk Insert の結果に置換されることなく、結果を次のコンポーネントに渡すために、たとえば次のようにして、成功メッセージを対象変数に保存することが考えられます。

  • 対象変数: bulkInsertResult

これで、フローの次の操作でこのペイロードにあるレコードを処理できます。