リアクティブインフラストラクチャ

このセクションでは、Spring Vault を使用したリアクティブプログラミングのサポートに関する基本情報について説明します。

リアクティブプログラミングとは何ですか?

簡単に言うと、リアクティブプログラミングとは、非同期でイベント駆動型であり、水平方向(つまり、クラスタリングを通じて)ではなく垂直方向(つまり、JVM 内)にスケーリングするために少ないスレッドを必要とするノンブロッキングアプリケーションに関するものです。

リアクティブアプリケーションの重要な側面は、プロデューサーがコンシューマーを圧倒しないようにするメカニズムであるバックプレッシャーの概念です。たとえば、HTTP 接続が遅すぎる場合にデータベースから HTTP レスポンスに拡張するリアクティブコンポーネントのパイプラインでは、ネットワーク容量が解放されるまでデータリポジトリの速度が低下したり完全に停止したりすることもあります。

リアクティブ Vault クライアント

Spring Vault のリアクティブクライアントサポートは、コンポーザブル認証ステップと、Reactor Netty または Jetty を介した Spring の関数 WebClient 上に構築されており、完全にノンブロッキングのイベント駆動型 HTTP クライアントの両方を備えています。

これは、HTTP リクエストを認証するための VaultToken (Javadoc) のサプライヤーとして VaultTokenSupplier (Javadoc) を公開し、プライマリエントリポイントとして ReactiveVaultOperations (Javadoc) を公開します。VaultEndpointClientOptionsSSL のコア構成は、さまざまなクライアント実装で再利用されます。

パッケージ org.springframework.vault.core にあるクラス ReactiveVaultTemplate (Javadoc) は、Spring のリアクティブ Vault サポートの中心となるクラスで、Vault と対話するための豊富な機能セットを提供します。このテンプレートは、Vault のデータの読み取り、書き込み、削除を行うための便利な操作を提供し、ドメインオブジェクトと Vault データ間のマッピングを提供します。

一度設定されると、ReactiveVaultTemplate (Javadoc) はスレッドセーフとなり、複数のインスタンス間で再利用できます。

Vault ドキュメントとドメインクラス間のマッピングは、WebClient とそのコーデックに委譲することによって行われます。

ReactiveVaultTemplate (Javadoc) クラスは、インターフェース ReactiveVaultOperations (Javadoc) を実装します。可能な限り、ReactiveVaultOperations (Javadoc) のメソッドは、API と CLI に慣れている既存の Vault 開発者に API を馴染みのあるものにするために、Vault API で利用可能なメソッドにちなんで名付けられています。たとえば、"write"、"delete"、"read" などのメソッドがあります。設計ゴールは、Vault API と ReactiveVaultOperations (Javadoc) の使用をできるだけ簡単に移行できるようにすることでした。2 つの API の主な違いは、ReactiveVaultOperations (Javadoc) に JSON キーと値のペアではなくドメインオブジェクトを渡すことができることです。

ReactiveVaultTemplate (Javadoc) インスタンスの操作を参照する推奨方法は、そのインターフェース ReactiveVaultOperations (Javadoc) を使用することです。

ReactiveVaultTemplate (Javadoc) によって明示的に公開されていない機能では、いくつかの実行コールバックメソッドのいずれかを使用して、基礎となる API にアクセスできます。実行コールバックは、WebClient オブジェクトへの参照を提供します。詳細については、セクション実行コールバックを参照してください。

ここで、Spring コンテナーのコンテキストで Vault を操作する方法の例を見てみましょう。

Spring Vault Bean の登録と構成

Spring Vault の使用には、Spring コンテキストは必要ありません。ただし、管理対象コンテキスト内に登録された ReactiveVaultTemplate (Javadoc) および VaultTokenSupplier のインスタンスは、Spring IoC コンテナーによって提供されるライフサイクルイベントに参加します。これは、アプリケーションのシャットダウン時にアクティブな Vault セッションを破棄できます。また、アプリケーション全体で同じ ReactiveVaultTemplate (Javadoc) インスタンスを再利用することでもメリットがあります。

Spring Vault には、Spring コンテキスト内で使用する Bean 定義を提供するサポート構成クラスが付属しています。アプリケーション構成クラスは通常、AbstractVaultConfiguration (Javadoc) から拡張され、環境固有の追加の詳細を提供する必要があります。

AbstractVaultConfiguration (Javadoc) から拡張するには、` VaultEndpoint vaultEndpoint()` および ClientAuthentication clientAuthentication() メソッドを実装する必要があります。

例 1: Java ベースの Bean メタデータを使用した Spring Vault オブジェクトの登録
@Configuration
public class AppConfig extends AbstractReactiveVaultConfiguration {

    /**
     * Specify an endpoint for connecting to Vault.
     */
    @Override
    public VaultEndpoint vaultEndpoint() {
        return new VaultEndpoint();                            (1)
    }

    /**
     * Configure a client authentication.
     * Please consider a more secure authentication method
     * for production use.
     */
    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication("…");                   (2)
    }
}
1 デフォルトで https://localhost:8200 を指す新しい VaultEndpoint (Javadoc) を作成します。
2 このサンプルでは、すぐに開始できるように TokenAuthentication (Javadoc) を使用します。サポートされている認証方法の詳細については、[vault.core.authentication] を参照してください。

セッション管理

Spring Vault では、Vault リクエストを認証するためにトークンが必要です。認証の詳細については、[vault.core.authentication] を参照してください。リアクティブクライアントには、VaultTokenSupplier で契約が定義されているノンブロッキングトークンサプライヤーが必要です。トークンは静的にすることも、宣言された認証フローを通じて取得することもできます。Vault ログインは、認証された Vault の各対話で発生するべきではありませんが、セッショントークンはセッション全体で保持される必要があります。この側面は、ReactiveLifecycleAwareSessionManager (Javadoc) などの ReactiveSessionManager (Javadoc) を実装するセッションマネージャーによって処理されます。

実行コールバック

すべての Spring テンプレートクラスに共通する設計上の特徴の 1 つは、すべての機能がテンプレートの実行コールバックメソッドの 1 つにルーティングされることです。これにより、例外や必要なリソース管理が一貫して実行されるようになります。これは、Vault の場合よりも JDBC や JMS の場合に非常に重要でしたが、それでもアクセスとログ記録を行うための単一の場所を提供します。そのため、実行コールバックを使用することは、ReactiveVaultTemplate (Javadoc) のメソッドとして公開していない珍しい操作を実行するために Vault API にアクセスする推奨される方法です。

実行コールバックメソッドのリストを次に示します。

  • <T> TdoWithVault、 (Function<WebClient, ? extends T> clientCallback) は指定された WebClient の反応シーケンスを作成し、セッションコンテキストなしで Vault と対話できるようにします。

  • <T> TdoWithSession、 (Function<WebClient, ? extends T> clientCallback) は指定された WebClient の反応シーケンスを作成し、認証されたセッションで Vault と対話できるようにします。

コールバックを使用して Vault を初期化する例を次に示します。

reactiveVaultOperations.doWithVault(webClient -> {

    return webClient.put()
                    .uri("/sys/init")
                    .syncBody(request)
                    .retrieve()
                    .toEntity(VaultInitializationResponse.class);
});