Flex Gateway新着情報
Governance新着情報
Monitoring API Manager以降のページでは、さまざまなポリシータスクを完了するための Rust コード例を示します。ポリシーの Rust コードは src/lib.rs ファイルで実装します。
コード例は、Rust プログラミング言語に関する基礎知識があることを前提としています。Rust のプログラミングに関する詳細は、以下を参照してください。
| ポリシーを実装する際に、設定パラメーターの追加または再定義が必要になる場合もあります。 |
追加のポリシー機能を定義する前に、「ポリシーテンプレート」、「ラップされた関数」、「フローのキャンセル」でポリシーのソースコード構造について確認してください。
Flex Gateway ポリシー開発キット (PDK) には、ポリシーの実装を開始するためのテンプレートとして、ポリシープロジェクトの最初の src/lib.rs ファイルが用意されています。
// Copyright 2024 Salesforce, Inc. All rights reserved.
mod generated;
use anyhow::{anyhow, Result};
use pdk::hl::*;
use pdk::logger;
use crate::generated::config::Config;
// This filter shows how to log a specific request header.
// You can extend the function and use the configurations exposed in config.rs file
async fn request_filter(request_state: RequestState, _config: &Config) {
let headers_state = request_state.into_headers_state().await;
let token = headers_state.handler().header("Token").unwrap_or_default();
// Log the header value
logger::info!("Header value: {token}");
}
#[entrypoint]
async fn configure(launcher: Launcher, Configuration(bytes): Configuration) -> Result<()> {
let config: Config = serde_json::from_slice(&bytes).map_err(|err| {
anyhow!(
"Failed to parse configuration '{}'. Cause: {}",
String::from_utf8_lossy(&bytes),
err
)
})?;
let filter = on_request(|rs| request_filter(rs, &config));
launcher.launch(filter).await?;
Ok(())
}
ポリシーは簡単なログを実行します。受信した要求ごとに、ポリシーは INFO ログレベルでヘッダートークンを記録します。
以下の要素でポリシーを設定します。
use pdk::api::hl::*;: PDK のすべてのコンポーネントを lib.rs ソースコードにインポートします。
#[entrypoint] 関数: ポリシーが適用されたときに実行され、request_filter 関数を呼び出します。この関数の内部で定義された変数は、ポリシーが適用されている間は有効です。
#[entrypoint] 関数は、以下のパラメーターを受け取ります。
Launcher: 検索条件関数を設定します。
Configuration: policy-pdk-create-schema-definition.adocで定義されている設定パラメーターを提供します。
request_filter: ポリシーが適用される API インスタンスに送信される要求ごとに 1 回実行されます。この関数は、ポリシー例で実行される検索条件を実装します。この関数の中で定義されている変数は、要求の実行中に利用できます。
request_filter は、ラップされた関数の例です。
#[entrypoint] 関数はラップされた関数を実行します。
let filter = on_request(|rs| request_filter(rs, &config));
launcher.launch(filter).await?;
on_response または on_request ラッパーは、検索条件関数が実行されるタイミングを定義します。
#[entrypoint] 関数では、提供されている requests_filter と response_filter 以外のカスタム関数を定義することができます。requests_filter と response_filter は例に過ぎません。
前の例で示したように、受信要求を絞り込む代わりに、on_response ラッパーを使用して送信応答を処理することができます。
async fn response_filter(response_state: ResponseState, _config: &Config) {
...
}
#[entrypoint]
async fn configure(launcher: Launcher, Configuration(bytes): Configuration) -> Result<()> {
let config: Config = serde_json::from_slice(&bytes).map_err(|err| {
anyhow!(
"Failed to parse configuration '{}'. Cause: {}",
String::from_utf8_lossy(&bytes),
err
)
})?;
let filter = on_response(|rs| response_filter(rs, &config));
launcher.launch(filter).await?;
Ok(())
}
request_filter 関数は response_filter 関数になりました。
|
要求と応答の両方を絞り込むには、両方のラッパーを使用します。
async fn request_filter(request_state: RequestState,_config: &Config) {
...
}
async fn response_filter(response_state: ResponseState,_config: &Config) {
...
}
#[entrypoint]
async fn configure(launcher: Launcher, Configuration(bytes): Configuration) -> Result<()> {
let config: Config = serde_json::from_slice(&bytes).map_err(|err| {
anyhow!(
"Failed to parse configuration '{}'. Cause: {}",
String::from_utf8_lossy(&bytes),
err
)
})?;
let filter = on_request(|rs| request_filter(rs, &config))
.on_response(|rs| response_filter(rs, &config));
launcher.launch(filter).await?;
Ok(())
}
カスタムポリシーはシングルスレッド環境で実行されます。ただし、ラップされた関数 (非同期関数の on_request と on_response) のすべてのセットは同時タスクとして実行されるため、単一ポリシーのインスタンスが複数の要求を同時に処理することになります。
この動作をサポートするために、すべての .await が潜在的なタスク中断ポイントとなります。.await が呼び出されると、基盤となる非同期ランタイムは現在のタスクをしばらくスリープさせて、まだ完了していない別のタスクを目覚めさせることができます。非同期ランタイムはタスクをキャンセルすることができ、最後の .await 呼び出しの後にあるコードを実行することはありません。 on_request 関数と on_response 関数は、.await 呼び出しが潜在的なキャンセルポイントであることを想定しています。
次のコード例に示すように、タスクキャンセルの最も一般的な状況は、要求関数がボディを待っている途中でアップストリームポリシーが応答を早期に返した場合です。
// Request function for upstream policy
async fn upstream_request(state: RequestState) -> Response {
Response::new(404)
}
// Request function for downstream policy
async fn downstream_request(state: RequestState) {
// Request function will be cancelled after this .await point.
let body_state = state.into_body_state().await;
// Code here will never be executed
}
PDK では、以下のポリシー機能のコード例が用意されています。追加のポリシー機能を定義する前に、ポリシーテンプレートとラップされた関数を確認してください。