7.6. 接続ファクトリーのアーティファクトとしてのデプロイ

このトピックでは、実際の推奨事項について説明します。

デプロイメント方法 では、javax.jms.ConnectionFactory サービスはアプリケーションコードによって直接登録されます。通常、このコードは Blueprint コンテナー内にあります。Blueprint XML は、通常の OSGi バンドルの一部である可能性があり、mvn: URI を使用してインストールでき、Maven リポジトリー (ローカルまたはリモート) に保存されます。Configuration Admin 設定と比較して、このようなバンドルのバージョン管理は簡単です。

pax-jms-config バージョン 1.0.0 バンドルは、接続ファクトリー設定の デプロイメント方法 を追加します。アプリケーション開発者は (通常 Bluerpint XML を使用して) javax.jms.(XA)ConnectionFactory サービスを登録し、サービスプロパティーを指定します。次に、pax-jms-config は、登録されたブローカー固有の接続ファクトリーを検出し、(サービスプロパティーを使用して) 汎用のブローカー固有でない接続プール内でサービスをラップします。

以下は、Blueprint XML を使用する 3 つの デプロイメント方法 です。

7.6.1. 接続ファクトリーの手動デプロイメント

この方法では、pax-jms-config バンドルは必要ありません。アプリケーションコードは、ブローカー固有および汎用接続プールの両方の登録を行います。

<!--
    Broker-specific, non-pooling, non-enlisting javax.jms.XAConnectionFactory
-->
<bean id="artemis" class="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory">
    <argument value="tcp://localhost:61616" />
    <property name="callTimeout" value="2000" />
    <property name="initialConnectAttempts" value="3" />
</bean>

<!--
    Fuse exports this service from fuse-pax-transx-tm-narayana bundle.
-->
<reference id="tm" interface="javax.transaction.TransactionManager" />

<!--
    Non broker-specific, generic, pooling, enlisting javax.jms.ConnectionFactory
-->
<bean id="pool" class="org.messaginghub.pooled.jms.JmsPoolXAConnectionFactory">
    <property name="connectionFactory" ref="artemis" />
    <property name="transactionManager" ref="tm" />
    <property name="maxConnections" value="10" />
    <property name="idleTimeout" value="10000" />
</bean>

<!--
    Expose connection factory for use by application code (such as Camel, Spring, ...)
-->
<service interface="javax.jms.ConnectionFactory" ref="pool">
    <service-properties>
        <!-- Giving connection factory a name using one of these properties makes identification easier in jms:connectionfactories: -->
        <entry key="osgi.jndi.service.name" value="jms/artemis" />
        <!--<entry key="name" value="jms/artemis" />-->
        <!-- Without any of the above, name will fall back to "service.id" -->
    </service-properties>
</service>

以下は、その使用方法を示すシェルコマンドです。

karaf@root()> feature:install artemis-core-client artemis-jms-client
karaf@root()> install -s mvn:org.apache.commons/commons-pool2/2.5.0
Bundle ID: 244
karaf@root()> install -s mvn:org.messaginghub/pooled-jms/0.3.0
Bundle ID: 245
karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-manual.xml
Bundle ID: 246

karaf@root()> bundle:services -p 246

Bundle 246 provides:
--------------------
objectClass = [javax.jms.ConnectionFactory]
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = pool
service.bundleid = 246
service.id = 340
service.scope = bundle
-----
objectClass = [org.osgi.service.blueprint.container.BlueprintContainer]
osgi.blueprint.container.symbolicname = artemis-manual.xml
osgi.blueprint.container.version = 0.0.0
service.bundleid = 246
service.id = 341
service.scope = singleton

karaf@root()> feature:install jms

karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis

karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product  │ ActiveMQ
version  │ 2.4.0.amq-711002-redhat-1

上記の一覧に示すように、Blueprint バンドルは、汎用的でブローカー固有でない接続プールである javax.jms.ConnectionFactory サービスをエクスポートします。Blueprint XML には明示的な <service ref="artemis"> 宣言がないため、ブローカー固有の javax.jms.XAConnectionFactory は OSGi サービスとして登録されません

7.6.2. 接続ファクトリーのファクトリーデプロイメント

このメソッドは、標準 の方法での pax-jms-config の使用方法を示しています。これは、Fuse 6.x で推奨されていた方法とは少し異なります。この方法では、サービスプロパティーとしてプーリング設定を指定する必要がありました。

Blueprint XML の例を以下に示します。

<!--
    A broker-specific org.ops4j.pax.jms.service.ConnectionFactoryFactory that can create (XA)ConnectionFactory
    using properties. It is registered by pax-jms-* bundles
-->
<reference id="connectionFactoryFactory"
        interface="org.ops4j.pax.jms.service.ConnectionFactoryFactory"
        filter="(type=artemis)" />

<!--
    Non broker-specific org.ops4j.pax.jms.service.PooledConnectionFactoryFactory that can create
    pooled connection factories with the help of org.ops4j.pax.jms.service.ConnectionFactoryFactory

    For example, pax-jms-pool-pooledjms bundle registers org.ops4j.pax.jms.service.PooledConnectionFactoryFactory
    with these properties:
     - pool = pooledjms
     - xa = true|false (both are registered)
-->
<reference id="pooledConnectionFactoryFactory"
        interface="org.ops4j.pax.jms.service.PooledConnectionFactoryFactory"
        filter="(&amp;(pool=pooledjms)(xa=true))" />

<!--
    When using XA connection factories, javax.transaction.TransactionManager service is not needed here.
    It is used internally by xa-aware pooledConnectionFactoryFactory.
-->
<!--<reference id="tm" interface="javax.transaction.TransactionManager" />-->

<!--
    Finally, use both factories to expose the pooled, xa-aware, connection factory.
-->
<bean id="pool" factory-ref="pooledConnectionFactoryFactory" factory-method="create">
    <argument ref="connectionFactoryFactory" />
    <argument>
        <props>
            <!--
                Properties needed by artemis-specific org.ops4j.pax.jms.service.ConnectionFactoryFactory
            -->
            <prop key="jms.url" value="tcp://localhost:61616" />
            <prop key="jms.callTimeout" value="2000" />
            <prop key="jms.initialConnectAttempts" value="3" />
            <!-- Properties needed by pooled-jms-specific org.ops4j.pax.jms.service.PooledConnectionFactoryFactory -->
            <prop key="pool.maxConnections" value="10" />
            <prop key="pool.idleTimeout" value="10000" />
        </props>
    </argument>
</bean>

<!--
    Expose connection factory for use by application code (such as Camel, Spring, ...)
-->
<service interface="javax.jms.ConnectionFactory" ref="pool">
    <service-properties>
        <!-- Giving connection factory a name using one of these properties makes identification easier in jms:connectionfactories: -->
        <entry key="osgi.jndi.service.name" value="jms/artemis" />
        <!--<entry key="name" value="jms/artemis" />-->
        <!-- Without any of the above, name will fall back to "service.id" -->
    </service-properties>
</service>

前述の例は、接続ファクトリーのファクトリーを使用して、接続ファクトリーを作成するファクトリー Bean を使用します。XA 対応の PooledConnectionFactoryFactory によって内部的に追跡されるため、javax.transaction.TransactionManager サービスを明示的に参照する必要はありません。

Fuse/Karaf シェルでは、以下のようになります。

karaf@root()> feature:install jms pax-jms-artemis pax-jms-pool-pooledjms

karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-pax-jms-factory-pooledjms.xml
Bundle ID: 253
karaf@root()> bundle:services -p 253

Bundle 253 provides:
--------------------
objectClass = [javax.jms.ConnectionFactory]
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = pool
service.bundleid = 253
service.id = 347
service.scope = bundle
-----
objectClass = [org.osgi.service.blueprint.container.BlueprintContainer]
osgi.blueprint.container.symbolicname = artemis-pax-jms-factory-pooledjms.xml
osgi.blueprint.container.version = 0.0.0
service.bundleid = 253
service.id = 348
service.scope = singleton

karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis

karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product  │ ActiveMQ
version  │ 2.4.0.amq-711002-redhat-1

上記の一覧に示すように、Blueprint バンドルは、汎用的でブローカー固有でない接続プールである javax.jms.ConnectionFactory サービスをエクスポートします。Blueprint XML には明示的な <service ref="artemis"> 宣言がないため、ブローカー固有の javax.jms.XAConnectionFactory は OSGi サービスとして登録されません

7.6.3. 接続ファクトリーの混合デプロイメント

pax-jms-config 1.0.0 バンドルは、サービスプロパティーを使用して、プーリング接続ファクトリー内にブローカー固有の接続ファクトリーを ラッピング する別の方法を追加します。このメソッドは、Fuse 6.x での作業に使用した方法と同じです。

Blueprint XML の例を以下に示します。

<!--
    Broker-specific, non-pooling, non-enlisting javax.jms.XAConnectionFactory
-->
<bean id="artemis" class="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory">
    <argument value="tcp://localhost:61616" />
    <property name="callTimeout" value="2000" />
    <property name="initialConnectAttempts" value="3" />
</bean>

<!--
    Expose broker-specific connection factory with service properties.
    No need to expose pooling, enlisting, non broker-specific javax.jms.XAConnectionFactory. It will be registered
    automatically by pax-jms-config with the same properties as this <service>, but with a higher service.ranking
-->
<service id="pool" ref="artemis" interface="javax.jms.XAConnectionFactory">
    <service-properties>
        <!-- "pool" key is needed for pax-jms-config to wrap broker-specific connection factory inside connection pool -->
        <entry key="pool" value="pooledjms" />
        <!-- <service>/@id attribute does not propagate, but name of the connection factory is required using one of: -->
        <entry key="osgi.jndi.service.name" value="jms/artemis" />
        <!-- or: -->
        <!--<entry key="name" value="jms/artemis" />-->
        <!-- Other properties, that normally by e.g., pax-jms-pool-pooledjms -->
        <entry key="pool.maxConnections" value="10" />
        <entry key="pool.idleTimeout" value="10000" />
    </service-properties>
</service>

上記の例では、ブローカー固有の接続ファクトリーのみを手動で登録できます。pool=pooledjms サービスプロパティーは、pax-jms-config バンドルによって管理される接続ファクトリートラッカーのヒントです。このサービスプロパティーを持つ接続ファクトリーサービスは、プール接続ファクトリー内でラップされます (この例では pax-jms-pool-pooledjms

Fuse/Karaf シェルでは、以下のようになります。

karaf@root()> feature:install jms pax-jms-config pax-jms-artemis pax-jms-pool-pooledjms

karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-pax-jms-discovery.xml
Bundle ID: 254

karaf@root()> bundle:services -p 254

Bundle 254 provides:
--------------------
objectClass = [javax.jms.XAConnectionFactory]
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = artemis
pool = pooledjms
pool.idleTimeout = 10000
pool.maxConnections = 10
service.bundleid = 254
service.id = 349
service.scope = bundle
-----
objectClass = [org.osgi.service.blueprint.container.BlueprintContainer]
osgi.blueprint.container.symbolicname = artemis-pax-jms-discovery.xml
osgi.blueprint.container.version = 0.0.0
service.bundleid = 254
service.id = 351
service.scope = singleton

karaf@root()> service:list javax.jms.XAConnectionFactory
[javax.jms.XAConnectionFactory]
-------------------------------
 osgi.jndi.service.name = jms/artemis
 osgi.service.blueprint.compname = artemis
 pool = pooledjms
 pool.idleTimeout = 10000
 pool.maxConnections = 10
 service.bundleid = 254
 service.id = 349
 service.scope = bundle
Provided by :
 Bundle 254
Used by:
 OPS4J Pax JMS Config (251)

karaf@root()> service:list javax.jms.ConnectionFactory
[javax.jms.ConnectionFactory]
-----------------------------
 osgi.jndi.service.name = jms/artemis
 osgi.service.blueprint.compname = artemis
 pax.jms.managed = true
 pax.jms.service.id.ref = 349
 pool.idleTimeout = 10000
 pool.maxConnections = 10
 service.bundleid = 251
 service.id = 350
 service.ranking = 1000
 service.scope = singleton
Provided by :
 OPS4J Pax JMS Config (251)

karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis

karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product  │ ActiveMQ
version  │ 2.4.0.amq-711002-redhat-1

前述の例では、このコマンドは重複した名前を削除するため、jms:connectionfactories は 1 つのサービスのみを示しています。データソースの混合デプロイメントにおいて、2 つのサービスが jdbc:ds-list によって表されました。

javax.jms.XAConnectionFactory は Blueprint バンドルから登録され、pool = pooledjms プロパティーが宣言されています。

javax.jms.ConnectionFactorypax-jms-config バンドルから登録されます。また、

  • pool = pooledjms プロパティーがありません。ラッパー接続ファクトリーの登録時に削除されました。
  • service.ranking = 1000 プロパティーがあるため、名前で接続ファクトリーを検索する場合など、常に優先されるバージョンになります。
  • pax.jms.managed = true プロパティーがあるので、再度ラップが試行されていません。
  • これには、接続プール内でラップされる元の接続ファクトリーサービスを示す pax.jms.service.id.ref = 349 プロパティーがあります。