46.4. プログラミングモデル

概要

API コンポーネントフレームワークのコンテキストでは、主なコンポーネント実装クラスは org.apache.camel.util.component パッケージのベースクラスから派生します。これらのベースクラスは、コンポーネントの実装時に (任意で) オーバーライドできるメソッドを定義します。このセクションでは、これらのメソッドと、コンポーネントの実装でこれらを使用する方法についての概要を説明します。

実装するコンポーネントメソッド

生成されるメソッド実装 (通常は変更する必要はありません) のほかに、Component クラスの以下のメソッドの一部を任意で上書きすることもできます。

doStart()
(任意) コールド起動時にコンポーネントのリソースを作成するためのコールバック。別の方法としては、遅延初期化 の設定 (リソースが必要な場合のみ作成) を実行する方法があります。実際、遅延初期化が最適なストラテジーとなることが多いため、doStart メソッドは必要ないことがよくあります。
doStop()

(任意) コンポーネントが停止している間にコードを呼び出すコールバック。コンポーネントを停止すると、そのリソースがすべてシャットダウンされ、内部状態が削除され、キャッシュが消去されることを意味します。

注記

Camel は、対応する doStart が呼び出されなかった場合でも、現在の CamelContext のシャットダウン時に 常に doStop が呼び出されることを保証します。

doShutdown
(オプション) CamelContext がシャットダウンしている間にコードを呼び出すコールバック。停止したコンポーネントを再起動することはできますが (コールドスタートのセマンティクスを使用)、シャットダウンするコンポーネントが完全に終了します。したがって、このコールバックは、コンポーネントに属するリソースを解放する最後の可能性を表します。

その他に Component クラスに実装するもの

Component クラスは、コンポーネントオブジェクト自体に同じ (または同様の) ライフサイクルを持つオブジェクトへの参照を保持するための最適な場所です。たとえば、コンポーネントが OAuth セキュリティーを使用する場合、Component クラスで必要な OAuth オブジェクトへの参照を保持し、OAuth オブジェクトを作成するための Component クラスでメソッドを定義するのが一般的です。

実装するエンドポイントメソッド

生成されたメソッドの一部を変更でき、必要に応じて以下のように Endpoint クラスで継承されたメソッドの一部を上書きすることができます。

afterConfigureProperties()

この方法で必要なのは、API 名に一致するプロキシークラス (API クラス) を作成することです。継承された apiName フィールドまたは getApiName アクセッサーを介して、(すでにエンドポイント URI から抽出されている) API 名を利用できます。通常、apiName フィールドでスイッチを実行して、対応するプロキシークラスを作成します。以下に例を示します。

// Java
private Object apiProxy;
...
@Override
protected void afterConfigureProperties() {
    // TODO create API proxy, set connection properties, etc.
    switch (apiName) {
        case HELLO_FILE:
            apiProxy = new ExampleFileHello();
            break;
        case HELLO_JAVADOC:
            apiProxy = new ExampleJavadocHello();
            break;
        default:
            throw new IllegalArgumentException("Invalid API name " + apiName);
    }
}
getApiProxy(ApiMethod method, Map<String, Object> args)

このメソッドを上書きして、afterConfigureProperties で作成したプロキシーインスタンスを返します。以下に例を示します。

@Override
public Object getApiProxy(ApiMethod method, Map<String, Object> args) {
    return apiProxy;
}

特殊なケースでは、API メソッドおよび引数に依存するプロキシーを選択する必要がある場合があります。必要に応じて、getApiProxy で、このアプローチを柔軟に行うことができます。

doStart()
(任意) コールド起動時にリソースを作成するためのコールバック。Component.doStart() と同じセマンティクスがあります。
doStop()
(任意) コンポーネントが停止している間にコードを呼び出すコールバック。Component.doStop() と同じセマンティクスがあります。
doShutdown
(オプション) コンポーネントがシャットダウンしている間にコードを呼び出すコールバック。Component.doShutdown() と同じセマンティクスがあります。
interceptPropertyNames(Set<String> propertyNames)

(任意) API コンポーネントフレームワークは、エンドポイント URI と指定されたオプション値を使用して、呼び出す方法を決定します (オーバーロードおよびエイリアスによる曖昧さ)。ただし、コンポーネントが内部的にオプションまたはメソッドパラメーターを追加する場合、このフレームワークでは呼び出す適切な方法を判断するためにヘルプが必要になる場合があります。この場合、interceptPropertyNames メソッドをオーバーライドし、追加の (非表示または暗黙的) オプションを propertyNames セットに追加する必要があります。メソッドパラメーターの完全なリストが propertyNames セットにあると、フレームワークは呼び出す適切なメソッドを特定できます。

注記

このメソッドは EndpointProducer、または Consumer クラスのレベルで上書きできます。基本的なルールは、オプションがプロデューサーエンドポイントとコンシューマーエンドポイントの 両方 に影響する場合に、Endpoint クラスのメソッドを上書きします。

interceptProperties(Map<String,Object> properties)

(任意) このメソッドを上書きすると、API メソッドが呼び出される前に、オプションの実際の値を変更または設定できます。たとえば、この方法を使用して、必要に応じて、一部のオプションにデフォルト値を設定できます。実際には、interceptPropertyNames メソッドおよび interceptProperty メソッドの両方を上書きする必要があることが多いです。

注記

このメソッドは EndpointProducer、または Consumer クラスのレベルで上書きできます。基本的なルールは、オプションがプロデューサーエンドポイントとコンシューマーエンドポイントの 両方 に影響する場合に、Endpoint クラスのメソッドを上書きします。

実装するコンシューマーメソッド

任意で、以下のように Consumer クラスで継承されたメソッドの一部を上書きできます。

interceptPropertyNames(Set<String> propertyNames)
(任意) このメソッドのセマンティクスは、Endpoint.interceptPropertyNames と似ています。
interceptProperties(Map<String,Object> properties)
(任意) このメソッドのセマンティクスは、Endpoint.interceptProperties と似ています。
doInvokeMethod(Map<String, Object> args)

(任意) このメソッドを上書きすると、Java API メソッドの呼び出しを妨害できます。このメソッドを上書きする最も一般的な理由は、メソッド呼び出しに関するエラー処理をカスタマイズすることです。たとえば、以下のコードフラグメントに doInvokeMethod を上書きする一般的な方法が示されています。

// Java
@Override
protected Object doInvokeMethod(Map<String, Object> args) {
    try {
        return super.doInvokeMethod(args);
    } catch (RuntimeCamelException e) {
        // TODO - Insert custom error handling here!
        ...
    }
}

Java API メソッドが呼び出されるように、この実装のある時点で doInvokeMethod をスーパークラスで呼び出す必要があります。

interceptResult(Object methodResult, Exchange resultExchange)
(任意) API メソッド呼び出しの結果に追加処理を行います。たとえば、この時点でカスタムヘッダーを Camel エクスチェンジオブジェクト resultExchange に追加できます。
Object splitResult(Object result)

(任意) デフォルトでは、メソッド API 呼び出しの結果が java.util.Collection オブジェクトまたは Java 配列である場合、API コンポーネントフレームワークは結果を 複数 のエクスチェンジオブジェクトに分割します (したがって、単一の呼び出しの結果が複数のメッセージに変換されます)。

デフォルトの動作を変更する場合は、コンシューマーエンドポイントで splitResult メソッドを上書きすることができます。result 引数には、API メッセージ呼び出しの結果が含まれます。結果を分割する場合は、配列タイプを返す必要があります。

注記

エンドポイント URI で consumer.splitResult=false に設定して、デフォルトの分割動作をオフにすることもできます。

実装するプロデューサーメソッド

任意で、以下のように継承されたメソッドの一部を Producer クラスで上書きできます。

interceptPropertyNames(Set<String> propertyNames)
(任意) このメソッドのセマンティクスは、Endpoint.interceptPropertyNames と似ています。
interceptProperties(Map<String,Object> properties)
(任意) このメソッドのセマンティクスは、Endpoint.interceptProperties と似ています。
doInvokeMethod(Map<String, Object> args)
(任意) このメソッドのセマンティクスは、Consumer.doInvokeMethod と似ています。
interceptResult(Object methodResult, Exchange resultExchange)
(任意) このメソッドのセマンティクスは、Consumer.interceptResult と似ています。
注記

Producer.splitResult() メソッドは呼び出しされないため、API メソッドの結果を、コンシューマーエンドポイントの場合と同じ方法で分割することはできません。プロデューサーエンドポイントに対して同様の効果を取得するには、Camel の split() DSL コマンド (標準のエンタープライズ統合パターンの 1 つ) を使用して Collection または配列の結果を分割できます。

コンシューマーポーリングおよびスレッドモデル

API コンポーネントフレームワークのコンシューマーエンドポイントのデフォルトのスレッドモデルは、スケジュールされたポーリングコンシューマーです。これは、コンシューマーエンドポイントの API メソッドが、定期的なスケジュールされた時間間隔で呼び出されることを意味します。詳細は、「スケジュールされたポーリングコンシューマーの実装」 を参照してください。