2.7. プロパティープレースホルダー
概要
プロパティープレースホルダー機能は、さまざまなコンテキスト (エンドポイント URI や XML DSL 要素の属性など) で文字列を置き換えるために使用できます。プレースホルダーの設定は Java プロパティーファイルに格納されます。この機能は、異なる Apache Camel アプリケーション間で設定を共有する場合や、特定の設定を一元管理する場合に役立ちます。
たとえば、以下のルートはリクエストを Web サーバーに送信します。この Web サーバーのホストとポートは、プレースホルダーの {{remote.host}}
と {{remote.port}}
に置き換えられます。
from("direct:start").to("http://{{remote.host}}:{{remote.port}}");
プレースホルダーの値は、以下のように Java プロパティーファイルに定義されています。
# Java properties file remote.host=myserver.com remote.port=8080
プロパティープレースホルダーはエンコーディングオプションをサポートし、UTF-8 などの特定の文字セットを使用して、.properties
ファイルの読み取りを可能にします。ただし、デフォルトでは ISO-8859-1 文字セットによる実装になります。
PropertyPlaceholders
を使用した Apache Camel では、以下がサポートされます。
- 検索するキーと共にデフォルト値を指定する。
-
すべてのプレースホルダーキーがデフォルト値で設定されていて、それらが使用される場合、
PropertiesComponent
を定義する必要がない。 サードパーティー関数を使用してプロパティー値を検索する。これにより、独自のロジックを実装できます。
注記プロパティー値を検索する関数として、標準で OS 環境変数、JVM システムプロパティー、サービス名イディオムの 3 つを提供します。
プロパティーファイル
プロパティー設定は 1 つ以上の Java プロパティーファイルに格納され、標準の Java プロパティーファイル形式に準拠する必要があります。各プロパティー設定は、それぞれ独立した行に Key=Value
の形式で表示されます。空白以外の最初の文字が #
または !
から始まる行は、コメントとして扱われます。
たとえば、プロパティーファイルは 例2.4「プロパティーファイルの例」 のような内容になります。
例2.4 プロパティーファイルの例
# Property placeholder settings # (in Java properties file format) cool.end=mock:result cool.result=result cool.concat=mock:{{cool.result}} cool.start=direct:cool cool.showid=true cheese.end=mock:cheese cheese.quote=Camel rocks cheese.type=Gouda bean.foo=foo bean.bar=bar
プロパティーの解決
Properties コンポーネントは、ルート定義の中で使用を開始する前に、1 つ以上のプロパティーファイルのロケーションを指定して設定しておく必要があります。以下のいずれかのリゾルバーを使用して、プロパティー値を提供する必要があります。
classpath:PathName,PathName,…
- (デフォルト) クラスパス上のロケーションを指定します。PathName は、フォワードスラッシュを使用して区切られたファイルパス名です。
file:PathName,PathName,…
- ファイルシステムのロケーションを指定します。PathName はフォワードスラッシュを使用して区切られたファイルパス名です。
ref:BeanID
-
レジストリーの
java.util.Properties
オブジェクトの ID を指定します。 blueprint:BeanID
-
cm:property-placeholder
Bean の ID を指定します。この Bean は、OSGi Blueprint ファイルのコンテキスト内で、OSGi Configuration Admin サービスで定義されたプロパティーにアクセスするために使用されます。詳細は、「OSGi Blueprint プロパティープレースホルダーとの統合」 を参照してください。
たとえば、クラスパス上にある com/fusesource/cheese.properties
プロパティーファイルと com/fusesource/bar.properties
プロパティーファイルを指定するには、以下のようなロケーション文字列を使用します。
com/fusesource/cheese.properties,com/fusesource/bar.properties
クラスパスリゾルバーはデフォルトで使用されるため、この例では classpath:
接頭辞は省略できます。
システムプロパティーと環境変数を使用したロケーションの指定
ロケーション PathName に Java システムプロパティーおよび O/S 環境変数を埋め込むことができます。
Java システムプロパティーは、${PropertyName}
構文を使用してロケーションリゾルバーに埋め込むことができます。たとえば、Red Hat Fuse のルートディレクトリーが Java システムプロパティー karaf.home
に保存されている場合、以下のようにそのディレクトリーの値をファイルロケーションに埋め込むことができます。
file:${karaf.home}/etc/foo.properties
O/S 環境変数は、${env:VarName}
構文を使用してロケーションリゾルバーに埋め込むことができます。たとえば、Fuse のルートディレクトリーが環境変数 SMX_HOME
に保存されている場合、以下のようにそのディレクトリーの値をファイルロケーションに埋め込むことができます。
file:${env:SMX_HOME}/etc/foo.properties
Properties コンポーネントの設定
プロパティープレースホルダーの使用を開始する前に、1 つ以上のプロパティーファイルのロケーションを指定して、Properties コンポーネントを設定する必要があります。
Java DSL では、以下のように Properties コンポーネントにプロパティーファイルのロケーションを設定できます。
// Java import org.apache.camel.component.properties.PropertiesComponent; ... PropertiesComponent pc = new PropertiesComponent(); pc.setLocation("com/fusesource/cheese.properties,com/fusesource/bar.properties"); context.addComponent("properties", pc);
addComponent()
の呼び出しに示されているように、Properties コンポーネントの名前を properties
に設定する 必要があります。
XML DSL では、以下のように専用の propertyPlacholder
要素を使用して Properties コンポーネントを設定できます。
<camelContext ...> <propertyPlaceholder id="properties" location="com/fusesource/cheese.properties,com/fusesource/bar.properties" /> </camelContext>
Properties コンポーネントの初期化時に見つからない .properties
ファイルを、Properties コンポーネントに無視させる場合は、ignoreMissingLocation
オプションを true
に設定します (通常、.properties
ファイルが見つからない場合はエラーが発生します)。
また、Java システムプロパティーまたは O/S 環境変数を使用して、指定されたロケーションが見つからないときに Properties コンポーネントが無視するようにする場合も、ignoreMissingLocation
オプションを true
に設定することができます。
プレースホルダー構文
Properties コンポーネントは、設定後は (適切なコンテキストで) プレースホルダーを自動的に置き換えます。プレースホルダーの構文は、以下のようにコンテキストによって異なります。
-
エンドポイント URI および Spring XML ファイル: プレースホルダーは
{{Key}}
のように指定します。 XML DSL の属性設定時:
xs:string
属性は以下の構文で設定します。AttributeName="{{Key}}"
その他の属性タイプ (
xs:int
またはxs:boolean
など) は、以下の構文を使用して設定する必要があります。prop:AttributeName="Key"
prop
は、http://camel.apache.org/schema/placeholder
名前空間に関連付けられています。Java DSL の EIP オプション設定時: Java DSL でエンタープライズ統合パターン (EIP) コマンドにオプションを設定するには、流れるような DSL に以下の
placeholder()
句を追加します。.placeholder("OptionName", "Key")
-
Simple 言語式: プレースホルダーは
${properties:Key}
. のように指定します。
エンドポイント URI 内での置換
ルートの中でエンドポイント URI 文字列が現れると、そのエンドポイント URI を構文解析する最初のステップは、常にプロパティープレースホルダーパーサーを適用することです。プレースホルダーパーサーは、二重かっこ {{Key}}
の間に表示されるプロパティー名を自動的に置換します。たとえば、例2.4「プロパティーファイルの例」 にあるプロパティー設定では、以下のようにルートを定義できます。
from("{{cool.start}}") .to("log:{{cool.start}}?showBodyType=false&showExchangeId={{cool.showid}}") .to("mock:{{cool.result}}");
デフォルトでは、プレースホルダーパーサーはレジストリーから properties
Bean ID を検索し、Properties コンポーネントを検索します。必要であれば、エンドポイント URI でスキーマを明示的に指定できます。たとえば、各エンドポイント URI に接頭辞 properties:
を付けて、以下のように同等のルートを定義できます。
from("properties:{{cool.start}}") .to("properties:log:{{cool.start}}?showBodyType=false&showExchangeId={{cool.showid}}") .to("properties:mock:{{cool.result}}");
スキーマを明示的に指定する場合、Properties コンポーネントにオプションを指定することもできます。たとえば、プロパティーファイルのロケーションを上書きするために、以下のように location
オプションを設定できます。
from("direct:start").to("properties:{{bar.end}}?location=com/mycompany/bar.properties");
Spring XML ファイル内での置換
XML DSL で DSL 要素のさまざまな属性を設定するために、プロパティープレースホルダーを使用することもできます。このコンテキストにおいても、プレースホルダー構文には二重かっこ {{Key}}
を使用します。たとえば、以下のようにプロパティープレースホルダーを使用して jmxAgent
要素を定義できます。
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <propertyPlaceholder id="properties" location="org/apache/camel/spring/jmx.properties"/> <!-- we can use property placeholders when we define the JMX agent --> <jmxAgent id="agent" registryPort="{{myjmx.port}}" usePlatformMBeanServer="{{myjmx.usePlatform}}" createConnector="true" statisticsLevel="RoutesOnly" /> <route> <from uri="seda:start"/> <to uri="mock:result"/> </route> </camelContext>
XML DSL 属性値の置換
xs:string
型の属性値を指定するには、通常のプレースホルダー構文を使用できます (例: <jmxAgent registryPort="{{myjmx.port}}" …>
)。しかし、他の型の属性 (例: xs:int
や xs:boolean
) については、特別な構文 prop:AttributeName="Key"
を使用する必要があります。
たとえば、プロパティーファイルで stop.flag
プロパティーの値が true
に定義されている場合、このプロパティーを使用して以下のように stopOnException
ブール値属性を設定できます。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:prop="http://camel.apache.org/schema/placeholder" ... > <bean id="illegal" class="java.lang.IllegalArgumentException"> <constructor-arg index="0" value="Good grief!"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/spring"> <propertyPlaceholder id="properties" location="classpath:org/apache/camel/component/properties/myprop.properties" xmlns="http://camel.apache.org/schema/spring"/> <route> <from uri="direct:start"/> <multicast prop:stopOnException="stop.flag"> <to uri="mock:a"/> <throwException ref="damn"/> <to uri="mock:b"/> </multicast> </route> </camelContext> </beans>
prop
接頭辞は、前述の例の beans
要素に示されるように、Spring ファイルの http://camel.apache.org/schema/placeholder
名前空間に明示的に割り当てられている必要があります。
Java DSL における EIP オプションの置換
Java DSL で EIP コマンドを呼び出す場合は、placeholder("OptionName", "Key")
の形式のサブ句を追加することで、プロパティープレースホルダーの値を使用した EIP オプションの設定ができます。
たとえば、プロパティーファイルで stop.flag
プロパティーの値が true
に定義されている場合、このプロパティーを使用して以下のように Multicast EIP の stopOnException
オプションを設定できます。
from("direct:start") .multicast().placeholder("stopOnException", "stop.flag") .to("mock:a").throwException(new IllegalAccessException("Damn")).to("mock:b");
Simple 言語式内での置換
Simple 言語の式の中でプロパティープレースホルダーを置換することもできますが、この場合プレースホルダーの構文は ${properties:Key}
になります。たとえば、以下のようにして Simple 式内の cheese.quote
プレースホルダーを置換できます。
from("direct:start") .transform().simple("Hi ${body} do you think ${properties:cheese.quote}?");
構文 ${properties:Key:DefaultVal}
を使用すると、プロパティーのデフォルト値を指定できます。以下に例を示します。
from("direct:start") .transform().simple("Hi ${body} do you think ${properties:cheese.quote:cheese is good}?");
構文 ${properties-location:Location:Key}
を使用して、プロパティーファイルのロケーションをオーバーライドすることもできます。たとえば、com/mycompany/bar.properties
プロパティーファイルの設定を使用して、bar.quote
プレースホルダーを置き換えるには、以下のように Simple 式を定義します。
from("direct:start") .transform().simple("Hi ${body}. ${properties-location:com/mycompany/bar.properties:bar.quote}.");
XML DSL 内でのプロパティープレースホルダーの使用
以前のリリースでは、 XML DSL のプレースホルダーをサポートするために xs:string
型の属性が使用されていました。たとえば、timeout 属性は xs:int
型になります。したがって、文字列の値をプレースホルダーキーとして設定することはできませんでした。
Apache Camel 2.7 以降、特別なプレースホルダーの名前空間を使用することでそれが可能になりました。以下の例は、その名前空間を使うための prop 接頭辞を示しています。これにより、XML DSL の属性に prop 接頭辞を付けて使用できます。
Multicast において、キー stop
を使用してプレースホルダーの値をオプション stopOnException
に設定しています。また、プロパティーファイルの中で以下の値を定義しています。
stop=true
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:prop="http://camel.apache.org/schema/placeholder" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd "> <!-- Notice in the declaration above, we have defined the prop prefix as the Camel placeholder namespace --> <bean id="damn" class="java.lang.IllegalArgumentException"> <constructor-arg index="0" value="Damn"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/spring"> <propertyPlaceholder id="properties" location="classpath:org/apache/camel/component/properties/myprop.properties" xmlns="http://camel.apache.org/schema/spring"/> <route> <from uri="direct:start"/> <!-- use prop namespace, to define a property placeholder, which maps to option stopOnException={{stop}} --> <multicast prop:stopOnException="stop"> <to uri="mock:a"/> <throwException ref="damn"/> <to uri="mock:b"/> </multicast> </route> </camelContext> </beans>
OSGi Blueprint プロパティープレースホルダーとの統合
Red Hat Fuse の OSGi コンテナーにルートをデプロイする場合、Apache Camel プロパティープレースホルダーのメカニズムを Fuse が持つ Blueprint プロパティープレースホルダーのメカニズムと統合できます (実際には、この統合はデフォルトで有効になっています) 。統合のセットアップには、基本的に以下の 2 つの方法があります。
暗黙的な Blueprint の統合
OSGi Blueprint ファイル内で camelContext
要素を定義すると、Apache Camel プロパティープレースホルダーのメカニズムは自動的に Blueprint プロパティープレースホルダーのメカニズムと統合します。つまり、camelContext
のスコープ内に現れる Apache Camel 構文に従ったプレースホルダー (例: {{cool.end}}
) は、暗黙的に blueprint property placeholder のメカニズムを検索することで解決されます。
たとえば、OSGi Blueprint ファイルで定義された以下のようなルートがあるとします。ルートの最後のエンドポイントは、プロパティープレースホルダー {{result}}
で定義されています。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <!-- OSGI blueprint property placeholder --> <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint"> <!-- list some properties for this test --> <cm:default-properties> <cm:property name="result" value="mock:result"/> </cm:default-properties> </cm:property-placeholder> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <!-- in the route we can use {{ }} placeholders which will look up in blueprint, as Camel will auto detect the OSGi blueprint property placeholder and use it --> <route> <from uri="direct:start"/> <to uri="mock:foo"/> <to uri="{{result}}"/> </route> </camelContext> </blueprint>
Blueprint プロパティープレースホルダーのメカニズムは、cm:property-placeholder
Bean を作成することで初期化されます。上記の例では、cm:property-placeholder
Bean は camel.blueprint
永続化 ID に関連付けられています。永続化 ID は、OSGi Configuration Admin サービスから関連するプロパティーのグループを参照する標準的な方法です。つまり、cm:property-placeholder
Bean は、camel.blueprint
永続化 ID の下で定義されたすべてのプロパティーへのアクセスを提供します。一部のプロパティーにデフォルト値を指定することもできます (ネストされた cm:property
要素を使用します)。
Blueprint のコンテキストでは、Apache Camel プレースホルダーのメカニズムは Bean レジストリー内の cm:property-placeholder
インスタンスを検索します。このインスタンスが見つかると、Apache Camel プレースホルダーのメカニズムと自動的に統合され、{{result}}
のようなプレースホルダーは Blueprint プロパティープレースホルダーのメカニズムに対して (この例では myblueprint.placeholder
Bean を通して) キーを検索することで解決されます。
デフォルトの Blueprint プレースホルダー構文 (Blueprint プロパティーに直接アクセスする) は ${Key}
です。そのため、camelContext
要素の 範囲外 では、使用しなければならないプレースホルダー構文は ${Key}
になります。しかし、camelContext
要素の 範囲内 では、使用しなければならないプレースホルダー構文は {{Key}}
になります。
明示的な Blueprint の統合
Apache Camel プロパティープレースホルダーのメカニズムがプロパティーを探す場所をさらに制御する場合は、propertyPlaceholder
要素を定義してリゾルバーのロケーションを明示的に指定できます。
たとえば、以下の Blueprint の設定について考えるとします。この例は、明示的に propertyPlaceholder
インスタンスを作成している点が前述の例とは異なっています。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 ">https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <!-- OSGI blueprint property placeholder --> <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint"> <!-- list some properties for this test --> <cm:default-properties> <cm:property name="result" value="mock:result"/> </cm:default-properties> </cm:property-placeholder> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <!-- using Camel properties component and refer to the blueprint property placeholder by its id --> <propertyPlaceholder id="properties" location="blueprint:myblueprint.placeholder"/> <!-- in the route we can use {{ }} placeholders which will lookup in blueprint --> <route> <from uri="direct:start"/> <to uri="mock:foo"/> <to uri="{{result}}"/> </route> </camelContext> </blueprint>
前述の例では、propertyPlaceholder
要素は、場所を blueprint:myblueprint.placeholder
に設定することにより、使用する cm:property-placeholder
Bean を明示的に指定します。つまり、blueprint:
リゾルバーは、cm:property-placeholder
Bean の ID myblueprint.placeholder
を明示的に参照します。
このスタイルによる設定は、Blueprint ファイルに複数の cm:property-placeholder
Bean が定義されていて、どれを使用すべきかを指定する必要がある場合に有効です。また、ロケーションをコンマ区切りのリストで指定することで、複数のロケーションからプロパティーを取得することも可能になります。たとえば、cm:property-placeholder
Bean とクラスパス上のプロパティーファイル myproperties.properties
の両方からプロパティーを検索する場合、以下のように propertyPlaceholder
要素を定義します。
<propertyPlaceholder id="properties" location="blueprint:myblueprint.placeholder,classpath:myproperties.properties"/>
Spring プロパティープレースホルダーとの統合
Spring XML ファイルの XML DSL を使用して Apache Camel アプリケーションを定義している場合、org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer
型の Spring Bean を宣言することで、Apache Camel プロパティープレースホルダーのメカニズムを Spring プロパティープレースホルダーのメカニズムと統合できます。
BridgePropertyPlaceholderConfigurer
を定義します。これは、Spring XML ファイルの Apache Camel の propertyPlaceholder
要素と Spring の ctx:property-placeholder
要素の両方を置き換えます。その後、Spring の ${PropName}
構文または Apache Camel の {{PropName}}
構文のいずれかを使用して、設定したプロパティーを参照できます。
たとえば、cheese.properties
ファイルからプロパティー設定を読み取るブリッジプロパティープレースホルダーを定義するとします。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ctx="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- Bridge Spring property placeholder with Camel --> <!-- Do not use <ctx:property-placeholder ... > at the same time --> <bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer"> <property name="location" value="classpath:org/apache/camel/component/properties/cheese.properties"/> </bean> <!-- A bean that uses Spring property placeholder --> <!-- The ${hi} is a spring property placeholder --> <bean id="hello" class="org.apache.camel.component.properties.HelloBean"> <property name="greeting" value="${hi}"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- Use Camel's property placeholder {{ }} style --> <route> <from uri="direct:{{cool.bar}}"/> <bean ref="hello"/> <to uri="{{cool.end}}"/> </route> </camelContext> </beans>
または、Spring プロパティーファイルを指すように、BridgePropertyPlaceholderConfigurer
の location
属性を設定することもできます。Spring プロパティーファイルの構文は完全にサポートされます。