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 -
url、userおよび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-mysql、pax-jdbc-oracle など) のバンドルでは、org.osgi.service.jdbc.DataSourceFactory サービスを登録でき、それを使用して、指定のデータベースのデータソースを取得できます (「データベース固有のデータソースおよび汎用データソース」参照)。しかし、実際のデータソースはまだありません。
mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.3.0 バンドルは、以下の 2 つを行う管理対象サービスファクトリーを提供します。
メソッドを呼び出すために、
org.osgi.service.jdbc.DataSourceFactoryOSGi サービスを追跡します。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 プロジェクトは、複数のデータベース製品および設定アプローチの機能を提供します。
/META-INF/services/java.sql.Driverで JDBC ドライバーをインストールします。karaf@root()> install -s mvn:mysql/mysql-connector-java/5.1.34 Bundle ID: 223
OSGi JDBC サービスバンドルと intermediary
org.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)
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
ファクトリー設定 を作成します (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 = fusepax-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.8.0.fuse-780038-redhat-00001/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 サービスなどのプロパティーとして、接頭辞を削除せずに追加されます。