検索

第295章 Camel SCR (非推奨)

download PDF

Camel 2.15 以降で利用可能

SCR は Service Component Runtime の略で、OSGi Declarative Services 仕様の実装です。SCR を使用すると、定型コードを使用せずに、プレーンな古い Java オブジェクトで OSGi サービスを公開して使用できます。

OSGi フレームワークは、通常は org.apache.felix:maven-scr-plugin などのプラグインによって Java アノテーションから生成されるバンドル内の SCR 記述子ファイルを調べることで、オブジェクトを認識します。

SCR バンドルで Camel を実行することは、Spring DM および Blueprint ベースのソリューションの優れた代替手段であり、OSGi フレームワークとの間のコード行が大幅に少なくなります。SCR を使用すると、バンドルは完全に Java の世界にとどまることができます。XML またはプロパティーファイルを編集する必要はありません。これにより、すべてを完全に制御でき、選択した IDE がプロジェクトで何が起こっているかを正確に認識できることを意味します。

295.1. Camel SCR サポート

Camel-scr バンドルは 2.15.0 より前の Apache Camel バージョンには含まれていませんが、アーティファクト自体は 2.12.0 以降のすべての Camel バージョンで使用できます。

org.apache.camel/camel-scr バンドルは、Camel コンテキストを管理する基本クラス AbstractCamelRunner と、単体テストで SCR プロパティーを使用するためのヘルパークラス ScrHelper を提供します。Apache Karaf の Camel-scr 機能は、SCR バンドルで Camel を実行するために必要なすべての機能とバンドルを定義します。

AbstractCamelRunner クラスは、CamelContext のライフサイクルをサービスコンポーネントのライフサイクルに結び付け、Camel の PropertiesComponent を使用して設定を処理します。Java クラスからサービスコンポーネントを作成するために必要なのは、それを AbstractCamelRunner から拡張し、クラスレベルで次の org.apache.felix.scr.annotations を追加することだけです。

必要なアノテーションを追加する

@Component
@References({
    @Reference(name = "camelComponent",referenceInterface = ComponentResolver.class,
        cardinality = ReferenceCardinality.MANDATORY_MULTIPLE, policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY, bind = "gotCamelComponent", unbind = "lostCamelComponent")
})

次に、実行する Camel ルートを返す getRouteBuilders() メソッドを実装します。

Implement getRouteBuilders()

    @Override
    protected List<RoutesBuilder> getRouteBuilders() {
        List<RoutesBuilder> routesBuilders = new ArrayList<>();
        routesBuilders.add(new YourRouteBuilderHere(registry));
        routesBuilders.add(new AnotherRouteBuilderHere(registry));
        return routesBuilders;
    }

最後に、デフォルト設定を次のように指定します。

アノテーションのデフォルト設定

@Properties({
   @Property(name = "camelContextId", value = "my-test"),
   @Property(name = "active", value = "true"),
   @Property(name = "...", value = "..."),
   ...
})

以上です。そして、camel-archetype-scr を使用してプロジェクトを生成した場合、これはすべてすでに処理されています。

以下は、camel-archetype-scr: によって生成された完全なサービスコンポーネントクラスの例です。

CamelScrExample.java

// This file was generated from org.apache.camel.archetypes/camel-archetype-scr/2.15-SNAPSHOT
package example;

import java.util.ArrayList;
import java.util.List;

import org.apache.camel.scr.AbstractCamelRunner;
import example.internal.CamelScrExampleRoute;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.spi.ComponentResolver;
import org.apache.felix.scr.annotations.*;

@Component(label = CamelScrExample.COMPONENT_LABEL, description = CamelScrExample.COMPONENT_DESCRIPTION, immediate = true, metatype = true)
@Properties({
    @Property(name = "camelContextId", value = "camel-scr-example"),
    @Property(name = "camelRouteId", value = "foo/timer-log"),
    @Property(name = "active", value = "true"),
    @Property(name = "from", value = "timer:foo?period=5000"),
    @Property(name = "to", value = "log:foo?showHeaders=true"),
    @Property(name = "messageOk", value = "Success: {{from}} -> {{to}}"),
    @Property(name = "messageError", value = "Failure: {{from}} -> {{to}}"),
    @Property(name = "maximumRedeliveries", value = "0"),
    @Property(name = "redeliveryDelay", value = "5000"),
    @Property(name = "backOffMultiplier", value = "2"),
    @Property(name = "maximumRedeliveryDelay", value = "60000")
})
@References({
    @Reference(name = "camelComponent",referenceInterface = ComponentResolver.class,
        cardinality = ReferenceCardinality.MANDATORY_MULTIPLE, policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY, bind = "gotCamelComponent", unbind = "lostCamelComponent")
})
public class CamelScrExample extends AbstractCamelRunner {

    public static final String COMPONENT_LABEL = "example.CamelScrExample";
    public static final String COMPONENT_DESCRIPTION = "This is the description for camel-scr-example.";

    @Override
    protected List<RoutesBuilder> getRouteBuilders() {
        List<RoutesBuilder> routesBuilders = new ArrayList<>();
        routesBuilders.add(new CamelScrExampleRoute(registry));
        return routesBuilders;
    }
}

CamelContextIdactive プロパティーは、CamelContext の名前 (デフォルトは "camel-runner-default") と、それを開始するかどうか (デフォルトは "false") をそれぞれ制御します。これらに加えて、好きなだけプロパティーを追加して使用できます。Camel の PropertiesComponent は、再帰的なプロパティーとフォールバックの接頭辞を問題なく処理します。

AbstractCamelRunner は、Camel の PropertiesComponent を使用して、これらのプロパティーを RouteBuilders で利用できるようにし、名前が一致する場合、サービスコンポーネントと RouteBuilder のフィールドにもこれらの値を注入します。フィールドは任意の可視性レベルで宣言でき、多くの型がサポートされています (String、int、boolean、URL など)。

以下は camel-archetype-scr によって生成された RouteBuilder クラスの例です:

CamelScrExampleRoute.java

// This file was generated from org.apache.camel.archetypes/camel-archetype-scr/2.15-SNAPSHOT
package example.internal;

import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.SimpleRegistry;
import org.apache.commons.lang.Validate;

public class CamelScrExampleRoute extends RouteBuilder {

    SimpleRegistry registry;

    // Configured fields
    private String camelRouteId;
    private Integer maximumRedeliveries;
    private Long redeliveryDelay;
    private Double backOffMultiplier;
    private Long maximumRedeliveryDelay;

    public CamelScrExampleRoute(final SimpleRegistry registry) {
        this.registry = registry;
    }

    @Override
    public void configure() throws Exception {
        checkProperties();

        // Add a bean to Camel context registry
        registry.put("test", "bean");

        errorHandler(defaultErrorHandler()
            .retryAttemptedLogLevel(LoggingLevel.WARN)
            .maximumRedeliveries(maximumRedeliveries)
            .redeliveryDelay(redeliveryDelay)
            .backOffMultiplier(backOffMultiplier)
            .maximumRedeliveryDelay(maximumRedeliveryDelay));

        from("{{from}}")
            .startupOrder(2)
            .routeId(camelRouteId)
            .onCompletion()
                .to("direct:processCompletion")
            .end()
            .removeHeaders("CamelHttp*")
            .to("{{to}}");


        from("direct:processCompletion")
            .startupOrder(1)
            .routeId(camelRouteId + ".completion")
            .choice()
                .when(simple("${exception} == null"))
                    .log("{{messageOk}}")
                .otherwise()
                    .log(LoggingLevel.ERROR, "{{messageError}}")
            .end();
        }
    }

    public void checkProperties() {
        Validate.notNull(camelRouteId, "camelRouteId property is not set");
        Validate.notNull(maximumRedeliveries, "maximumRedeliveries property is not set");
        Validate.notNull(redeliveryDelay, "redeliveryDelay property is not set");
        Validate.notNull(backOffMultiplier, "backOffMultiplier property is not set");
        Validate.notNull(maximumRedeliveryDelay, "maximumRedeliveryDelay property is not set");
    }
}

CamelScrExampleRoute をさらに詳しく見てみましょう。

    // Configured fields
    private String camelRouteId;
    private Integer maximumRedeliveries;
    private Long redeliveryDelay;
    private Double backOffMultiplier;
    private Long maximumRedeliveryDelay;

これらのフィールドの値は、名前を一致させることにより、プロパティからの値で設定されます。

        // Add a bean to Camel context registry
        registry.put("test", "bean");

ルート用にいくつかの Bean を CamelContext のレジストリーに追加する必要がある場合は、次のように実行できます。

    public void checkProperties() {
        Validate.notNull(camelRouteId, "camelRouteId property is not set");
        Validate.notNull(maximumRedeliveries, "maximumRedeliveries property is not set");
        Validate.notNull(redeliveryDelay, "redeliveryDelay property is not set");
        Validate.notNull(backOffMultiplier, "backOffMultiplier property is not set");
        Validate.notNull(maximumRedeliveryDelay, "maximumRedeliveryDelay property is not set");
    }

ルートの開始を許可する前に、必要なパラメーターが設定されていて、それらに意味のある値があることを確認することを推奨します。

        from("{{from}}")
            .startupOrder(2)
            .routeId(camelRouteId)
            .onCompletion()
                .to("direct:processCompletion")
            .end()
            .removeHeaders("CamelHttp*")
            .to("{{to}}");


        from("direct:processCompletion")
            .startupOrder(1)
            .routeId(camelRouteId + ".completion")
            .choice()
                .when(simple("${exception} == null"))
                    .log("{{messageOk}}")
                .otherwise()
                    .log(LoggingLevel.ERROR, "{{messageError}}")
            .end();

ルートのほとんどすべてがプロパティーで設定されていることに注意してください。これにより、基本的に RouteBuilder がテンプレートになります。SCR を使用すると、代替設定を提供するだけで、ルートのインスタンスをさらに作成できます。詳細については、Camel SCR バンドルをテンプレートとして使用する セクションを参照してください。

Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.