6.4. OSGi JDBC サービスの使用

OSGi Enterprise R6 仕様の第 125 章には、 org.osgi.service.jdbc パッケージの単一のインターフェイスが定義されています。これは、OSGi がデータソースを処理する方法です。

public interface DataSourceFactory {

    java.sql.Driver createDriver(Properties props);

    javax.sql.DataSource createDataSource(Properties props);

    javax.sql.ConnectionPoolDataSource createConnectionPoolDataSource(Properties props);

    javax.sql.XADataSource createXADataSource(Properties props);
}

前述のように、java.sql.Driver からプレーン java.sql.Connection 接続を直接取得できる可能性があります。

Generic org.osgi.service.jdbc.DataSourceFactory

org.osgi.service.jdbc.DataSourceFactory の最も単純な実装は、mvn:org.ops4j.pax.jdbc/pax-jdbc/1.3.0 バンドルが提供する org.ops4j.pax.jdbc.impl.DriverDataSourceFactory です。これはすべて、標準の Java™ ServiceLoader ユーティリティーの /META-INF/services/java.sql.Driver 記述子が含まれる可能性のあるバンドルを追跡するだけです。標準の JDBC ドライバーをインストールする場合、pax-jdbc バンドルは java.sql.Driver.connect() 呼び出しを使用して接続を取得するために (直接ではなく) 使用できる DataSourceFactory を登録します。

karaf@root()> install -s mvn:org.osgi/org.osgi.service.jdbc/1.0.0
Bundle ID: 223
karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc/1.3.0
Bundle ID: 224
karaf@root()> install -s mvn:org.postgresql/postgresql/42.2.5
Bundle ID: 225
karaf@root()> install -s mvn:mysql/mysql-connector-java/5.1.34
Bundle ID: 226

karaf@root()> bundle:services -p org.postgresql.jdbc42

PostgreSQL JDBC Driver JDBC42 (225) provides:
---------------------------------------------
objectClass = [org.osgi.service.jdbc.DataSourceFactory]
osgi.jdbc.driver.class = org.postgresql.Driver
osgi.jdbc.driver.name = PostgreSQL JDBC Driver
osgi.jdbc.driver.version = 42.2.5
service.bundleid = 225
service.id = 242
service.scope = singleton

karaf@root()> bundle:services -p com.mysql.jdbc

Oracle Corporation's JDBC Driver for MySQL (226) provides:
----------------------------------------------------------
objectClass = [org.osgi.service.jdbc.DataSourceFactory]
osgi.jdbc.driver.class = com.mysql.jdbc.Driver
osgi.jdbc.driver.name = com.mysql.jdbc
osgi.jdbc.driver.version = 5.1.34
service.bundleid = 226
service.id = 243
service.scope = singleton
-----
objectClass = [org.osgi.service.jdbc.DataSourceFactory]
osgi.jdbc.driver.class = com.mysql.fabric.jdbc.FabricMySQLDriver
osgi.jdbc.driver.name = com.mysql.jdbc
osgi.jdbc.driver.version = 5.1.34
service.bundleid = 226
service.id = 244
service.scope = singleton

karaf@root()> service:list org.osgi.service.jdbc.DataSourceFactory
[org.osgi.service.jdbc.DataSourceFactory]
-----------------------------------------
 osgi.jdbc.driver.class = org.postgresql.Driver
 osgi.jdbc.driver.name = PostgreSQL JDBC Driver
 osgi.jdbc.driver.version = 42.2.5
 service.bundleid = 225
 service.id = 242
 service.scope = singleton
Provided by :
 PostgreSQL JDBC Driver JDBC42 (225)

[org.osgi.service.jdbc.DataSourceFactory]
-----------------------------------------
 osgi.jdbc.driver.class = com.mysql.jdbc.Driver
 osgi.jdbc.driver.name = com.mysql.jdbc
 osgi.jdbc.driver.version = 5.1.34
 service.bundleid = 226
 service.id = 243
 service.scope = singleton
Provided by :
 Oracle Corporation's JDBC Driver for MySQL (226)

[org.osgi.service.jdbc.DataSourceFactory]
-----------------------------------------
 osgi.jdbc.driver.class = com.mysql.fabric.jdbc.FabricMySQLDriver
 osgi.jdbc.driver.name = com.mysql.jdbc
 osgi.jdbc.driver.version = 5.1.34
 service.bundleid = 226
 service.id = 244
 service.scope = singleton
Provided by :
 Oracle Corporation's JDBC Driver for MySQL (226)

上記のコマンドは、登録までの手順の 1 つで、javax.sql.DataSource サービスはまだ登録されません。上記の org.osgi.service.jdbc.DataSourceFactory の中間サービスを使用して以下を取得できます。

  • java.sql.Driver
  • urluser および password のプロパティーを createDataSource() メソッドに渡す javax.sql.DataSource

データベース固有ではない pax-jdbc で作成された汎用の org.osgi.service.jdbc.DataSourceFactory から javax.sql.ConnectionPoolDataSource または javax.sql.XADataSource を取得できません。

注記

mvn:org.postgresql/postgresql/42.2.5 バンドルは OSGi JDBC 仕様を正しく実装し、XA および ConnectionPool データソースを作成するメソッドを含む、実装されているすべてのメソッドで org.osgi.service.jdbc.DataSourceFactory インスタンスを登録します。

データベース固有の org.osgi.service.jdbc.DataSourceFactory 専用実装

以下のような追加のバンドルがあります。

  • mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.3.0
  • mvn:org.ops4j.pax.jdbc/pax-jdbc-db2/1.3.0
  • …​

これらのバンドルは、javax.sql.ConnectionPoolDataSource および javax.sql.XADataSource など、全種の ファクトリー を返すことができる、データベース固有の org.osgi.service.jdbc.DataSourceFactory サービスを登録します。以下に例を示します。

karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.3.0
Bundle ID: 227

karaf@root()> bundle:services -p org.ops4j.pax.jdbc.mysql

OPS4J Pax JDBC MySQL Driver Adapter (227) provides:
---------------------------------------------------
objectClass = [org.osgi.service.jdbc.DataSourceFactory]
osgi.jdbc.driver.class = com.mysql.jdbc.Driver
osgi.jdbc.driver.name = mysql
service.bundleid = 227
service.id = 245
service.scope = singleton

karaf@root()> service:list org.osgi.service.jdbc.DataSourceFactory
...
[org.osgi.service.jdbc.DataSourceFactory]
-----------------------------------------
 osgi.jdbc.driver.class = com.mysql.jdbc.Driver
 osgi.jdbc.driver.name = mysql
 service.bundleid = 227
 service.id = 245
 service.scope = singleton
Provided by :
 OPS4J Pax JDBC MySQL Driver Adapter (227)

6.4.1. PAX-JDBC 設定サービス

pax-jdbc (または pax-jdbc-mysqlpax-jdbc-oracle など​) のバンドルでは、org.osgi.service.jdbc.DataSourceFactory サービスを登録でき、それを使用して、指定のデータベースのデータソースを取得できます (「データベース固有のデータソースおよび汎用データソース」参照)。しかし、実際のデータソースはまだありません。

mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.3.0 バンドルは、以下の 2 つを行う管理対象サービスファクトリーを提供します。

  • メソッドを呼び出すために、org.osgi.service.jdbc.DataSourceFactory OSGi サービスを追跡します。

    public DataSource createDataSource(Properties props);
    public XADataSource createXADataSource(Properties props);
    public ConnectionPoolDataSource createConnectionPoolDataSource(Properties props);
  • org.ops4j.datasource ファクトリー PID を追跡し、上記のメソッドに必要なプロパティーを収集します。たとえば、${karaf.etc}/org.ops4j.datasource-mysql.cfg ファイルの作成など、Configuration Admin サービスで使用可能な任意の方法を使用して、ファクトリー設定を作成する場合は、最終的な手順を実行して、実際のデータベース固有のデータソースを公開できます。

以下は、Fuse の新規インストールを開始するために順をおって説明した 標準的な ガイドです。

注記

機能の代わりにバンドルを明示的にインストールし、必要なバンドルを正確に表示します。便宜上、PAX JDBC プロジェクトは、複数のデータベース製品および設定アプローチの機能を提供します。

  1. /META-INF/services/java.sql.Driver で JDBC ドライバーをインストールします。

    karaf@root()> install -s mvn:mysql/mysql-connector-java/5.1.34
    Bundle ID: 223
  2. OSGi JDBC サービスバンドルと intermediaryorg.osgi.service.jdbc.DataSourceFactory を登録する pax-jdbc-mysql バンドルをインストールします。

    karaf@root()> install -s mvn:org.osgi/org.osgi.service.jdbc/1.0.0
    Bundle ID: 224
    karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.3.0
    Bundle ID: 225
    
    karaf@root()> service:list org.osgi.service.jdbc.DataSourceFactory
    [org.osgi.service.jdbc.DataSourceFactory]
    -----------------------------------------
     osgi.jdbc.driver.class = com.mysql.jdbc.Driver
     osgi.jdbc.driver.name = mysql
     service.bundleid = 225
     service.id = 242
     service.scope = singleton
    Provided by :
     OPS4J Pax JDBC MySQL Driver Adapter (225)
  3. pax-jdbc バンドルおよび、org.osgi.service.jdbc.DataSourceFactory サービス およびorg.ops4j.datasource ファクトリー PID を追跡する pax-jdbc-config バンドルをインストールします。

    karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc/1.3.0
    Bundle ID: 226
    karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.3.0
    Bundle ID: 227
    karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.3.0
    Bundle ID: 228
    
    karaf@root()> bundle:services -p org.ops4j.pax.jdbc.config
    
    OPS4J Pax JDBC Config (228) provides:
    -------------------------------------
    objectClass = [org.osgi.service.cm.ManagedServiceFactory]
    service.bundleid = 228
    service.id = 245
    service.pid = org.ops4j.datasource
    service.scope = singleton
  4. ファクトリー設定 を作成します (MySQL サーバーが実行中であると想定します)。

    karaf@root()> config:edit --factory --alias mysql org.ops4j.datasource
    karaf@root()> config:property-set osgi.jdbc.driver.name mysql
    karaf@root()> config:property-set dataSourceName mysqlds
    karaf@root()> config:property-set url jdbc:mysql://localhost:3306/reportdb
    karaf@root()> config:property-set user fuse
    karaf@root()> config:property-set password fuse
    karaf@root()> config:update
    
    karaf@root()> config:list '(service.factoryPid=org.ops4j.datasource)'
    ----------------------------------------------------------------
    Pid:            org.ops4j.datasource.a7941498-9b62-4ed7-94f3-8c7ac9365313
    FactoryPid:     org.ops4j.datasource
    BundleLocation: ?
    Properties:
       dataSourceName = mysqlds
       felix.fileinstall.filename = file:${karaf.etc}/org.ops4j.datasource-mysql.cfg
       osgi.jdbc.driver.name = mysql
       password = fuse
       service.factoryPid = org.ops4j.datasource
       service.pid = org.ops4j.datasource.a7941498-9b62-4ed7-94f3-8c7ac9365313
       url = jdbc:mysql://localhost:3306/reportdb
       user = fuse
  5. pax-jdbc-config が設定を処理して javax.sql.DataSource サービスに指定しているかどうかを確認します。

    karaf@root()> service:list javax.sql.DataSource
    [javax.sql.DataSource]
    ----------------------
     dataSourceName = mysqlds
     felix.fileinstall.filename = file:${karaf.etc}/org.ops4j.datasource-mysql.cfg
     osgi.jdbc.driver.name = mysql
     osgi.jndi.service.name = mysqlds
     password = fuse
     pax.jdbc.managed = true
     service.bundleid = 228
     service.factoryPid = org.ops4j.datasource
     service.id = 246
     service.pid = org.ops4j.datasource.a7941498-9b62-4ed7-94f3-8c7ac9365313
     service.scope = singleton
     url = jdbc:mysql://localhost:3306/reportdb
     user = fuse
    Provided by :
     OPS4J Pax JDBC Config (228)

これで、実際のデータベース固有 (まだプールなし) データソースができました。必要な場所に注入することができます。たとえば、Karaf コマンドを使用してデータベースにクエリーすることができます。

karaf@root()> feature:install -v jdbc
Adding features: jdbc/[4.2.0.fuse-000237-redhat-1,4.2.0.fuse-000237-redhat-1]
...
karaf@root()> jdbc:ds-list
Mon May 14 08:46:22 CEST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Name    │ Product │ Version │ URL                                  │ Status
────────┼─────────┼─────────┼──────────────────────────────────────┼───────
mysqlds │ MySQL   │ 5.7.21  │ jdbc:mysql://localhost:3306/reportdb │ OK

karaf@root()> jdbc:query mysqlds 'select * from incident'
Mon May 14 08:46:46 CEST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
date                  │ summary    │ name   │ details                       │ id │ email
──────────────────────┼────────────┼────────┼───────────────────────────────┼────┼─────────────────
2018-02-20 08:00:00.0 │ Incident 1 │ User 1 │ This is a report incident 001 │ 1  │ user1@redhat.com
2018-02-20 08:10:00.0 │ Incident 2 │ User 2 │ This is a report incident 002 │ 2  │ user2@redhat.com
2018-02-20 08:20:00.0 │ Incident 3 │ User 3 │ This is a report incident 003 │ 3  │ user3@redhat.com
2018-02-20 08:30:00.0 │ Incident 4 │ User 4 │ This is a report incident 004 │ 4  │ user4@redhat.com

上記の例では、MySQL の警告が表示されます。これは問題ではありません。すべてのプロパティー (OSGi JDBC 固有のものだけでなく) が提供されます。

karaf@root()> config:property-set --pid org.ops4j.datasource.a7941498-9b62-4ed7-94f3-8c7ac9365313 useSSL false

karaf@root()> jdbc:ds-list
Name    │ Product │ Version │ URL                                  │ Status
────────┼─────────┼─────────┼──────────────────────────────────────┼───────
mysqlds │ MySQL   │ 5.7.21  │ jdbc:mysql://localhost:3306/reportdb │ OK

6.4.2. 処理されたプロパティーの概要

管理 ファクトリー PID の設定からのプロパティーは、関連する org.osgi.service.jdbc.DataSourceFactory 実装に渡されます。

Generic

org.ops4j.pax.jdbc.impl.DriverDataSourceFactory properties:

  • url
  • user
  • password

DB2

org.ops4j.pax.jdbc.db2.impl.DB2DataSourceFactory プロパティーには、以下の実装クラスのすべての bean プロパティーが含まれます。

  • com.ibm.db2.jcc.DB2SimpleDataSource
  • com.ibm.db2.jcc.DB2ConnectionPoolDataSource
  • com.ibm.db2.jcc.DB2XADataSource

PostgreSQL

Nnative org.postgresql.osgi.PGDataSourceFactory プロパティーには、org.postgresql.PGProperty に指定されたすべてのプロパティーが含まれます。

HSQLDB

org.ops4j.pax.jdbc.hsqldb.impl.HsqldbDataSourceFactory properties:

  • url
  • user
  • password
  • databaseName
  • すべての Bean プロパティー

    • org.hsqldb.jdbc.JDBCDataSource
    • org.hsqldb.jdbc.pool.JDBCPooledDataSource
    • org.hsqldb.jdbc.pool.JDBCXADataSource

SQL Server および Sybase

org.ops4j.pax.jdbc.jtds.impl.JTDSDataSourceFactory プロパティーには、net.sourceforge.jtds.jdbcx.JtdsDataSource のすべての Bean プロパティーが含まれます。

SQL Server

org.ops4j.pax.jdbc.mssql.impl.MSSQLDataSourceFactory プロパティー:

  • url
  • user
  • password
  • databaseName
  • serverName
  • portNumber
  • すべての Bean プロパティー

    • com.microsoft.sqlserver.jdbc.SQLServerDataSource
    • com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource
    • com.microsoft.sqlserver.jdbc.SQLServerXADataSource

MySQL

org.ops4j.pax.jdbc.mysql.impl.MysqlDataSourceFactory properties:

  • url
  • user
  • password
  • databaseName
  • serverName
  • portNumber
  • すべての Bean プロパティー

    • com.mysql.jdbc.jdbc2.optional.MysqlDataSource
    • com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
    • com.mysql.jdbc.jdbc2.optional.MysqlXADataSource

Oracle

org.ops4j.pax.jdbc.oracle.impl.OracleDataSourceFactory properties:

  • url
  • databaseName
  • serverName
  • user
  • password
  • すべての Bean プロパティー

    • oracle.jdbc.pool.OracleDataSource
    • oracle.jdbc.pool.OracleConnectionPoolDataSource
    • oracle.jdbc.xa.client.OracleXADataSource

SQLite

org.ops4j.pax.jdbc.sqlite.impl.SqliteDataSourceFactory properties:

  • url
  • databaseName
  • org.sqlite.SQLiteDataSource のすべての Bean プロパティー

6.4.3. pax-jdb-config バンドルがプロパティーを処理する方法

pax-jdbc-config バンドルは、jdbc. で始まるプロパティーを処理します。これらのプロパティーを使用すると、すべてこの接頭辞が削除され、残りの名前が引き継がれます。

以下に例を示します。こちらも、Fuse の新規インストールから始めます。

karaf@root()> install -s mvn:mysql/mysql-connector-java/5.1.34
Bundle ID: 223
karaf@root()> install -s mvn:org.osgi/org.osgi.service.jdbc/1.0.0
Bundle ID: 224
karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.3.0
Bundle ID: 225
karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc/1.3.0
Bundle ID: 226
karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.3.0
Bundle ID: 227
karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.3.0
Bundle ID: 228

karaf@root()> config:edit --factory --alias mysql org.ops4j.datasource
karaf@root()> config:property-set osgi.jdbc.driver.name mysql
karaf@root()> config:property-set dataSourceName mysqlds
karaf@root()> config:property-set dataSourceType DataSource
karaf@root()> config:property-set jdbc.url jdbc:mysql://localhost:3306/reportdb
karaf@root()> config:property-set jdbc.user fuse
karaf@root()> config:property-set jdbc.password fuse
karaf@root()> config:property-set jdbc.useSSL false
karaf@root()> config:update

karaf@root()> config:list '(service.factoryPid=org.ops4j.datasource)'
----------------------------------------------------------------
Pid:            org.ops4j.datasource.7c3ee718-7309-46a0-ae3a-64b38b17a0a3
FactoryPid:     org.ops4j.datasource
BundleLocation: ?
Properties:
   dataSourceName = mysqlds
   dataSourceType = DataSource
   felix.fileinstall.filename = file:/data/servers/7.11.1.fuse-7_11_1-00013-redhat-00003/etc/org.ops4j.datasource-mysql.cfg
   jdbc.password = fuse
   jdbc.url = jdbc:mysql://localhost:3306/reportdb
   jdbc.useSSL = false
   jdbc.user = fuse
   osgi.jdbc.driver.name = mysql
   service.factoryPid = org.ops4j.datasource
   service.pid = org.ops4j.datasource.7c3ee718-7309-46a0-ae3a-64b38b17a0a3

karaf@root()> service:list javax.sql.DataSource
[javax.sql.DataSource]
----------------------
 dataSourceName = mysqlds
 dataSourceType = DataSource
 felix.fileinstall.filename = file:${karaf.etc}/org.ops4j.datasource-mysql.cfg
 jdbc.password = fuse
 jdbc.url = jdbc:mysql://localhost:3306/reportdb
 jdbc.user = fuse
 jdbc.useSSL = false
 osgi.jdbc.driver.name = mysql
 osgi.jndi.service.name = mysqlds
 pax.jdbc.managed = true
 service.bundleid = 228
 service.factoryPid = org.ops4j.datasource
 service.id = 246
 service.pid = org.ops4j.datasource.7c3ee718-7309-46a0-ae3a-64b38b17a0a3
 service.scope = singleton
Provided by :
 OPS4J Pax JDBC Config (228)

pax-jdbc-config バンドルには以下のプロパティーが必要です

  • osgi.jdbc.driver.name
  • dataSourceName
  • dataSourceType

関連する org.osgi.service.jdbc.DataSourceFactory メソッドを見つけて呼び出すには、以下を実行します。jdbc. の接頭辞が付けられたプロパティーは (接頭辞の削除後)、org.osgi.service.jdbc.DataSourceFactory.createDataSource(properties) などに渡されます。ただし、これらのプロパティーは、javax.sql.DataSource OSGi サービスなどのプロパティーとして、接頭辞を削除せずに追加されます。