第274章 Camel SCR(非推奨)
Camel 2.15 から利用可能
SCR はサービスコンポーネントランタイムを表し、OSGi Declarative Services 仕様の実装です。SCR により、プレーンな古い Java オブジェクトが、ボイラープレートコードなしで OSGi サービスを公開し、使用できるようになります。
OSGi フレームワークは、通常 org.apache.felix:maven-scr-plugin
などのプラグインによって Java アノテーションから生成される SCR 記述子ファイルをバンドルで確認します。
Camel を SCR バンドルで実行することは、Spring DM と Blueprint ベースのソリューション向けの便利な選択肢で、ユーザーと OSGi フレームワーク間のコード行は大幅に少なくなります。SCR を使用すると、バンドルは完全に Java グローバルに残ることができます。XML やプロパティーファイルの編集は必要ありません。これにより、すべてを完全に制御でき、選択した IDE はプロジェクトで何が起こっているのかを正確に認識することを意味します。
274.1. Camel SCR のサポート
camel-scr バンドルは Apache Camel バージョン before 2.15.0 に含まれていませんが、アーティファクト自体は 2.12.0 以降の Camel バージョンで使用できます。
org.apache.camel/camel-scr
バンドルは、Camel コンテキストと、ユニットテストで SCR プロパティーを使用するためにヘルパークラス ScrHelper
を管理するベースクラス AbstractCamelRunner
を提供します。Apache Karaf の camel-scr 機能は、Camel を SCR バンドルで実行するために必要なすべての機能とバンドルを定義します。
AbstractCamelRunner
クラスは CamelContext のライフサイクルを Service Component のライフサイクルに結び付け、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 によって生成された完全な Service Component クラスの例になります
。
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; } }
CamelContextId
と アクティブな
プロパティーは、CamelContext の名前(デフォルトは「camel-runner-default」)を制御し、起動すべきかどうか(デフォルトは「false」)を制御します。これらの他に、任意の数のプロパティーを追加して使用できます。Camel の PropertiesComponent は、再帰的なプロパティーと、問題なくフォールバックを接頭辞として処理します。
AbstractCamelRunner
は、Camel の PropertiesComponent を利用してこれらのプロパティーを RouteBuilder で利用できるようにし、名前が一致するとそれらの値を Service Component のフィールドおよび 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 のレジストリーに追加する必要がある場合は、以下のように Bean を追加できます。
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 bundle をテンプレートとして使用する」を 参照してください。