DataWeave 式の使用

DataWeave 式を使用するポリシープロジェクトの例は、 「クエリポリシーの例」​を参照してください。

入力 DataWeave 式パラメーターが有効な場合、ポリシーは式を解析して ​pdk::script::Script​ 式に変換します。スクリプトの結果を得る手順は次のとおりです。

  1. Evaluator を作成します。

  2. スキーマ定義で定義されている各パラメーターのバインディング関数を呼び出します。

    • vars​: 各ポリシーの ​vars​ の ​bind_vars​ メソッドを呼び出します。すべての ​vars​ がバインドされた後、Evaluator は式の解決を試みます。式にスキーマで定義されている以外の ​vars​ が含まれている場合、それらは ​null​ に解決されます。

    • attributes​: bind_attributes​ メソッドを ​AttributesBinding​ trait の実装で呼び出します。Flex Gateway ポリシー開発キット (PDK) は、​RequestHeaderState​、​RequestHeaderState​、および ​HTTP コール​の応答のそれぞれに対して新しい ​HandlerAttributesBinding​ をインスタンス化することで、この trait を実装します。

    • authentication​: bind_authentication​ メソッドを ​AuthenticationBinding​ trait の実装で呼び出します。PDK は、​AuthenticationData​ に対してこの trait を実装しています。ポリシーに認証情報を挿入するには、​「認証情報の挿入」​を参照してください。

    • payload​: bind_payload​ メソッドを ​PayloadBinding​ の実装で呼び出します。PDK は、​RequestBodyState​、​ResponseBodyState​、および ​HTTP コール​の応答に対して、この trait の実装を提供します。

      スキーマ定義で定義されているバインディングのメソッドのみを呼び出します。たとえば、​attributes​ バインディングを使用しない場合は、​bind_attributes​ メソッドを呼び出さないでください。

      DataWeave 式の定義の詳細については、​「DataWeave 式」​を参照してください。

  3. すべての式変数をバインドしたら、​eval​ メソッドを呼び出して結果を取得します。

DataWeave 式の評価

たとえば、次のポリシースキーマ定義の ​tokenExtractor​ DataWeave 式を評価する手順は、次のとおりです。

apiVersion: gateway.mulesoft.com/v1alpha1
kind: Extension
metadata:
 labels:
   title: jwt-auth
   category: Custom
spec:
 extends:
   - name: extension-definition
     namespace: default
 properties:
   tokenExtractor:
     type: string
     format: dataweave
     default: "#[vars.myVar]"
     bindings:
       payload:
         mimeType: text
       attributes: true
       authentication: true
       vars:
         - myVar
 required:
   - tokenExtractor

以下の Rust スニペットを使用します。

// Copyright 2024 Salesforce, Inc. All rights reserved.
mod generated;


use anyhow::Result;


use crate::generated::config::Config;
use pdk::authentication::{Authentication, AuthenticationHandler};
use pdk::logger::info;
use pdk::hl::*;
use pdk::script::{Evaluator, HandlerAttributesBinding, Value};


async fn request_filter(
   state: RequestState,
   stream: StreamProperties,
   auth: Authentication,
   mut evaluator: Evaluator<'_>,
) {
   evaluator.bind_vars("myVar", "myVal");

   evaluator.bind_authentication(&auth.authentication());

   let state = state.into_headers_state().await;
   evaluator.bind_attributes(&HandlerAttributesBinding::new(state.handler(), &stream));

   let state = state.into_body_state().await;
   evaluator.bind_payload(&state);

   if let Ok(value) = evaluator.eval() {
       match value {
           Value::Null => info!("value was null!"),
           Value::Bool(val) => info!("value was Bool: {val}"),
           Value::Number(val) => info!("value was Number: {val}"),
           Value::String(val) => info!("value was String: {val}"),
           Value::Array(val) => info!("value was Array: {val:?}"),
           Value::Object(val) => info!("value was Object: {val:?}"),
       }
   }
}


#[entrypoint]
async fn configure(launcher: Launcher, Configuration(bytes): Configuration) -> Result<()> {
   let config: Config = serde_json::from_slice(&bytes)?;


   launcher
       .launch(on_request(|request, stream, auth| {
           request_filter(request, stream, auth, config.token_extractor.evaluator())
       }))
       .await?;
   Ok(())
}

式が解決されたことの確認

すべての値がバインドされる前に、いくつかの式を解決することができます。たとえば、​#[vars.myVar]​ という式を解決するためには、​attributes​、​payload​、そしていずれの ​authentication​ も解決する必要はありません。

バインディングメソッドのいずれかが呼び出された後、そのメソッドを呼び出すことで、式が完全に解決されたことを確認できます。

evaluator.is_ready()