制御バス

エンタープライズ統合パターン (英語) (EIP)ブックに従って、コントロールバスの背景となる考え方は、「アプリケーションレベル」メッセージングに使用されるのと同じメッセージングシステムをフレームワーク内のコンポーネントの監視と管理に使用できるということです。Spring Integration では、公開された操作を呼び出す手段としてメッセージを送信できるように、上記のアダプターに基づいて構築しています。

コントロールバスはシステム状態を変更できるほど強力なので、メッセージの受信を保護し (SecurityContextChannelInterceptor を参照)、コントロールバス管理 (メッセージソース) を DMZ にのみ公開することをお勧めします。

次の例は、XML で制御バスを構成する方法を示しています。

<int:control-bus input-channel="operationChannel"/>

制御バスには、アプリケーションコンテキストで Bean の操作を呼び出すためにアクセスできる入力チャネルがあります。また、エンドポイントをアクティブにするサービスのすべての共通プロパティもあります。例: 操作の結果に、ダウンストリームチャネルに送信する戻り値がある場合、出力チャネルを指定できます。

制御バスは、入力チャネル上のメッセージを、beanName.methodName のような単純な文字列形式で管理された操作として実行します。ターゲットメソッドパラメーターの引数は、IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS ヘッダーのリストとして指定する必要があります。Bean と呼び出すメソッドは、ControlBusCommandRegistry インフラストラクチャ Bean から解決されます。デフォルトでは、ControlBusCommandRegistry は要求に応じてコマンドを登録します。その eagerInitialization フラグは、@EnableIntegrationManagement(loadControlBusCommands = "true") を介してオンにできます。

コントロールバスの機能は JMX に似ているため、コマンドのメソッドの適格性は次の要件を満たす必要があります。

  • @ManagedAttribute または @ManagedOperation でアノテーションが付けられたメソッド。

  • Spring の Lifecycle インターフェース (およびバージョン 5.2 以降の Pausable 拡張)。

  • Spring の TaskExecutor および TaskScheduler 実装のいくつかを構成するために使用されるメソッド。

独自のメソッドをコントロールバスで使用できるようにする最も簡単な方法は、@ManagedAttribute または @ManagedOperation アノテーションを使用することです。これらのアノテーションはメソッドを JMX MBean レジストリに公開するためにも使用されるため、便利な副産物が提供されます。多くの場合、コントロールバスに公開する操作と同じ種類の操作は、JMX を介して公開するのに適しています。詳細については、ControlBusCommandRegistry および ControlBusMethodFilter Javadoc を参照してください。

Spring Bean でメソッドを実行するには、クライアントは次のように操作チャネルにメッセージを送信できます。

Message<?> operation = MessageBuilder.withPayload("myServiceBean.shutdown").build();
operationChannel.send(operation);

呼び出すターゲットメソッドに引数がある場合 (例: ThreadPoolTaskExecutor.setMaxPoolSize(int maxPoolSize))、それらの値は IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS ヘッダーとして提供する必要があります。

Message<?> operation =
        MessageBuilder.withPayload("myTaskExecutor.setMaxPoolSize")
        .setHeader(IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS, List.of(10))
        .build();
operationChannel.send(operation);

これらのコマンドは、パラメーターバインディングを持つ JDBC の PreparedStatement インスタンスと考えることができます。引数の型は、メソッドパラメーターの型と一致する必要があります。これらは、Java メソッドオーバーロード機能に従って呼び出すメソッドを選択するための追加条件として使用されます。たとえば、次のコンポーネントがあります。

@ManagedResource
class TestManagementComponent {

    @ManagedOperation
    public void operation() {

    }

    @ManagedOperation(description = "The overloaded operation with int argument")
    public void operation(int input) {

    }

    @ManagedOperation(description = "The overloaded operation with two arguments")
    public void operation(int input1, String input2) {

    }

    @ManagedOperation
    public int operation2() {
    	return 123;
    }

}

operation という名前の 3 つのコマンドを公開します。testManagementComponent.operation コマンドを呼び出すときは、ControlBusCommandRegistry が Bean 上のターゲットメソッドをフィルター処理できるように、IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS ヘッダーに適切な値のリストを選択する必要があります。

Java アノテーションを使用すると、制御バスを次のように構成できます。

@Bean
@ServiceActivator(inputChannel = "operationChannel")
public ControlBusFactoryBean controlBus() {
    return new ControlBusFactoryBean();
}

同様に、Java DSL フロー定義を次のように構成できます。

@Bean
public IntegrationFlow controlBusFlow() {
    return IntegrationFlow.from("controlBus")
              .controlBus()
              .get();
}

DirectChannel の自動作成でラムダを使用する場合は、次のように制御バスを作成できます。

@Bean
public IntegrationFlow controlBus() {
    return IntegrationFlowDefinition::controlBus;
}

この場合、チャネルの名前は controlBus.input です。

また、HTTP 経由でコントロールバス管理を公開するには、制御バス REST コントローラーを参照してください。