カスタム応答ポリシーの開発

カスタムポリシーを開発する準備ができたら、「Good Weather 社」の例に従って後で独自のポリシーを計画、開発、および実装する方法を学習します。ポリシーを作成する手順は、次のとおりです。

ユースケース

カスタムポリシーの実装方法についての理解を深めるため、特定の場所と時間の天気を予測する事業を行っている「Good Weather」社の例を考えてみます。Good Weather は、特定の場所の大気の現在の状態に関する定量的なデータを収集し、気象学を使用して、その現在の状態が経時的にどのように変化するかを予測します。

Good Weather は、現在の天気パターンに基づいて、コンシューム側アプリケーションの天気予報にカスタム応答を追加する機能を提供したいと考えています。アプリケーションは、各要求で評価される一連の条件に基づいて状況コードと応答メッセージを操作できる必要があります。

Telstra は、モバイルおよびホームコンピューティングテクノロジー用のオペレーティングシステムとアプリケーションを開発する IT 企業です。Telstra は Good Weather と連携して、モバイルと PC で毎日の天気予報を表示したいと考えています。

Good Weather は、基本認証ポリシーが適用された HTTP プロキシを使用しています。要求が到着するたびに、ポリシーはベアラートークンをチェックし、次のいずれかのタスクを実行します。

  • 要求がバックエンドに到達することを許可する

  • 検証が成功しなかった場合は、「401 Unauthorized (401 未承認)」状況コードで要求を拒否する。

ただし、未承認アクセスがあった場合、Telstra は 401 エラーを受信するたびに異なるメッセージを含めたいと考えている場合はどうでしょうか。カスタム応答ポリシーを開発することで、一連の異なる条件に基づいて応答メッセージと状況コードを変更できます。たとえば、応答に「Unauthorized (未承認)」状況コードが含まれている場合、それに応じて応答ペイロードを変更するように指定できます。

ただし、特定の条件に基づいた検証に失敗したときにアプリケーションでユーザーにカスタム応答を提供するようにした場合、デフォルトポリシーは機能しません。たとえば、Telstra はアプリケーションがエラーコードを返すだけでなく、追加の応答ペイロードも提供したいと考えているとします。このようなシナリオでは、カスタムポリシーを作成する必要があります。

プロジェクトのセットアップ

Telstra は、最初に​カスタムポリシーアーキタイププロジェクト​を作成することで、カスタムポリシーの開発を開始します。 次に、アーキタイプを実行し、ここで太字で示されているパラメーターを独自のパラメーターに置き換えます。

  • DgroupId​ は Telstra の組織 ID。

  • DartifactId​ は ​custom-response-policy​ 値。

    必要に応じて、他の任意の値に設定できます。

  • Dversion​ は 1.0.0。

    DartifactId​ と ​Dversion​ に制限はありません。

mvn -Parchetype-repository archetype:generate \
-DarchetypeGroupId=org.mule.tools \
-DarchetypeArtifactId=api-gateway-custom-policy-archetype \
-DarchetypeVersion=1.2.0 \
-DgroupId=<Telstra_organization_ID> \
-DartifactId=custom-response-policy \
-Dversion=1.0.0 \
-Dpackage=mule-policy

YAML 設定ファイルの作成

Telstra はプロジェクトをセットアップした後に、連動関係とコンポーネントの追加を開始してカスタマイズします。API Manager で設定するポリシーの入力パラメーターを定義することから始めます。

  1. 要求と応答の評価に使用する条件を指定します。

  2. 条件がパラメーターの場合、DataWeave 式が作成されます。

  3. API Manager は、同時に条件が満たされるかどうかを検証します。

  4. 条件が満たされた場合、状況コードが設定されます。

  5. 条件が満たされた場合、ペイロードが設定されます。

次のコードスニペットは、ポリシー UI の YAML ファイルの例を示しています。

  id: Custom Response
  name: Custom Response
  description: Modifies the payload and/or the status code when some condition is met.
  category: Custom
  type: custom
  resourceLevelSupported: true
  encryptionSupported: false
  standalone: true
  requiredCharacteristics: []
  providedCharacteristics: []
  configuration:
   - propertyName: evaluateInRequest
     name: Evaluate in the request
     description: If the condition should be evaluated in the request.
     type: boolean
     optional: true
     defaultValue: false
   - propertyName: requestCondition
     name: Request Condition
     description: Dataweave expression that will be evaluated to define if the request should be modified.
     type: expression
     optional: true
     sensitive: false
     allowMultiple: false
     dependsOnKey: evaluateInRequest
     dependsOnValue: true
   - propertyName: evaluateInResponse
     name: Evaluate in the response
     description: If the condition should be evaluated in the response.
     type: boolean
     optional: true
     defaultValue: false
   - propertyName: responseCondition
     name: Response Condition
     description: Dataweave expression that will be evaluated to define if the request should be modified.
     type: expression
     optional: true
     sensitive: false
     allowMultiple: false
     dependsOnKey: evaluateInResponse
     dependsOnValue: true
   - propertyName: mergeBothConditions
     name: Merge both conditions
     description: Check if both request and response conditions need to be met.
     type: boolean
     optional: true
     defaultValue: false
   - propertyName: statusCode
     name: Status Code
     type: int
     minimumValue: 0
     maximumValue: 999
     description: Status code to return when the condition is met.
     optional: true
     sensitive: false
     allowMultiple: false
   - propertyName: payload
     name: Payload
     type: expression
     description: Expression that sets the payload to return when the condition is met.
     optional: true
     sensitive: false
     allowMultiple: false

この例では、​dependsOnKey​ および ​dependsOnValue​ パラメーターは項目 ​responseCondition​ または ​requestCondition​ を表示するために、​dependsOnKey​ で示されるキーを ​dependsOnValue​ で示される値に設定する必要があることを指定しています。

UI では、これはチェックボックスの値に応じて、​requestCondition​ または ​responseCondition​ 項目のいずれかを表示する ​evaluateInTheRequest​ または ​evaluateInTheResponse​ のチェックボックスに変換されます。

YAML ファイルのセットアップ方法についての詳細は、​「YAML 設定ファイル」​を参照してください。

この例に基づき、UI は次のように生成されます。

custom-response-policy

次のスクリーンショットは、​dependsOnKey​ および ​dependsOnValue​ パラメーターを示しています。

depends-on-key-demo

ポリシーの実装

Telstra はポリシーの入力パラメーターを定義した後に、次の手順でポリシーの実装を開始できます。

  1. pom.xml​ ファイルに連動関係を追加します。

  2. template.xml​ ファイルに条件を追加します。

pom.xml ファイルへの連動関係の追加

新しい状況コードとペイロードを使用してカスタム応答を変換するため、Telstra は拡張機能を作成する必要があります。これにより、応答メッセージを変換する定型コードの開発を回避できます。

  1. pom.xml​ に Telstra が使用する必要があるすべての連動関係を含めます。

    この場合、​http-policy-transform-extension​ のみが必要になります。これは、応答情報を簡単に変更するのに役立ちます。

  2. ポリシー ​pom.xml​ ファイルの ​<dependencies>​ セクションに次の連動関係を含めます。

<dependency>
   <groupId>com.mulesoft.anypoint</groupId>
   <artifactId>mule-http-policy-transform-extension</artifactId>
   <version>${httpPolicyTransformVersion}</version>
   <classifier>mule-plugin</classifier>
</dependency>

Java で独自のコネクタを作成する方法についての詳細は、​「Java 用 Mule SDK 入門」​を参照してください。

template.xml ファイルへの条件の追加

次に、Telstra は YAML ファイルを Handlebars に関連付ける必要があります。YAML ファイルは、使用される式を作成したり、コードブロック全体を追加したりする XML の項目を完成させるために使用します。

Telstra は ​template.xml​ ファイルに次のコードを含める必要があります。

{{#if evaluateInRequest}}
<set-variable variableName="requestConditionMet" value="{{{requestCondition}}}" />
{{/if}}
<http-policy:execute-next/>
{{#if evaluateInResponse}}
<set-variable variableName="responseConditionMet" value="{{{responseCondition}}}" />
{{/if}}

二重中括弧 ({{}}) 内のコードは、YAML ファイルで定義された設定を含むポリシーテンプレートを作成するためにテンプレートエンジンを使用する、​Handlebars​ 構文に対応しています。テンプレートの設定に使用される値は、YAML 設定ファイルで以前に定義されたキーである必要があります。両方の値が一致する必要があります。いずれかのパラメーターのスペルが間違っていると、エラーが発生する可能性があります。

前の例では、パラメーター ​evaluateInRequest​ と ​evaluateInResponse​ は、​requestCondition​ と ​responseCondition​ で定義された評価される条件値を保持する要素を定義しています。

たとえば、ポリシーを設定するときに、特定のヘッダーが要求内に存在することを確認する必要があるとします。ただし、応答内は何も確認しないとします。この場合、ポリシー設定は次のようになります。

custom-response-configuration

デプロイされると、テンプレートは次のコード例に示すように解決されます。応答条件を指定しなかったため、Handlebars は解決されたテンプレートにそれを含めません。

<set-variable variableName="requestConditionMet" value="#[attributes.headers['X-MyHeader'] == 'MyValue']" />
<http-policy:execute-next/>

次に、Telstra は次のコードを使用してテンプレートファイルのロジックを完成させます。

<choice>
   {{#if mergeBothConditions}}
   <when expression="#[(vars.requestConditionMet default false) and (vars.responseConditionMet default false)]" >
       {{#if statusCode}}
       <set-variable variableName="statusCode" value="{{statusCode}}" />
       {{/if}}

       {{#if payload}}
       <set-variable variableName="payload" value="{{{payload}}}" />
       {{/if}}

       <http-transform:set-response statusCode="#[vars.statusCode default attributes.statusCode]">
           <http-transform:body>#[vars.payload default payload]</http-transform:body>
           <http-transform:headers>#[attributes.headers]</http-transform:headers>
       </http-transform:set-response>
   </when>
   {{else}}
   <when expression="#[(vars.requestConditionMet default false) or (vars.responseConditionMet default false)]" >
       {{#if statusCode}}
       <set-variable variableName="statusCode" value="{{statusCode}}" />
       {{/if}}

       {{#if payload}}
       <set-variable variableName="payload" value="{{{payload}}}" />
       {{/if}}

       <http-transform:set-response statusCode="#[vars.statusCode default attributes.statusCode]">
           <http-transform:body>#[vars.payload default payload]</http-transform:body>
           <http-transform:headers>#[attributes.headers]</http-transform:headers>
       </http-transform:set-response>
   </when>
   {{/if}}
</choice>

ペイロードと状況コード (設定されている場合) を変更するため、​連動関係​に含まれる ​http-policy-transform-extension​ パラメーターを使用します。

前述のように、テンプレートの一部を解決するために Handlebars が使用されていることがわかります。

これで、Telstra のカスタム応答ポリシーを Exchange にアップロードしてテストする準備が整いました。

Exchange へのアップロード

カスタムポリシーを Exchange にアップロードするため、Telstra は ​pom.xml​ ファイルが組織用に適切に設定されていることを確認する必要があります。

タスクの前提条件

ポリシーを Exchange にアップロードする前に、Telstra は次のことを確認する必要があります。

  • Maven ​settings.xml​ ファイルで新しいサーバーが作成されている。

  • 一意の ID が割り当てられ、Exchange ログイン情報のユーザー名とパスワードが存在する。

  • URL が自分の地域と一致する。

    警告:​ 同様のアクションを実行して独自のカスタムポリシーを作成する場合、テンプレートは米国地域に対応する URL を使用していることに注意してください。アカウントがこの地域に属していない場合は、この値を変更します。

  • リポジトリ ID が Maven 設定の ID と一致する。

    ヒント:​ name タグを使用して、そのリポジトリの別名を定義できます。

<servers>
      <server>
         <id>your_server_id</id>
         <username>your_username</username>
         <password>your_password</password>
       </server>
</servers>

次に、ポリシー ​pom.xml​ ファイルに移動して ​distributionManagement​ セクションを見つけます。

<distributionManagement>
    <repository>
        <id>your_server_id</id>
        <name>My Repository</name>
        <url>${exchange.url}</url>
        <layout>default</layout>
    </repository>
</distributionManagement>

サーバーの設定を確認したら、次のコマンドを使用して Exchange へのポリシーのアップロードを開始します。

> mvn deploy

これで、Telstra が開発したカスタムポリシーが Exchange にアップロードされました。

ポリシーの適用

次に、Telstra はデフォルトポリシーを適用するのと同じ方法でカスタムポリシーを適用します。API Manager に移動すると、使用可能な新しいポリシーが表示され、いつでも使用できます。

custom-response-policy-platform