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.Connection
연결은 java.sql.Driver
에서 직접 가져올 수 있습니다.
Generic org.osgi.service.jdbc.DataSourceFactory
org.osgi.service.jdbc.DataSourceFactory
의 가장 간단한 구현은 org.ops4j.pax.jdbc.impl.DriverDataSourceFactory
입니다. mvn:org.ops4j.pax.jdbc/pax-jdbc/pax-jdbc/1.3.0 번들이 제공하는 org.ops4j
.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)
위의 명령을 사용하면 javax.sql.DataSource
서비스가 아직 등록되지 않았지만 한 발짝 더 가깝습니다. 위의 중간 org.osgi.service.jdbc.DataSourceFactory
서비스를 사용하여 다음을 얻을 수 있습니다.
-
java.sql.Driver
-
속성을 전달하여
javax.sql.DataSource
:url
,user
및password
를createDataSource()
메서드에 전달합니다.
일반 org
sql.XADataSource를 가져올 수 없습니다. .osgi.service.jdbc.DataFactory에서
또는 javax.javax.sql.XADataSource
mvn:org.postgresql/postgresql/42.2.5
번들은 OSGi JDBC 사양을 올바르게 구현하고 org.osgi.service.jdbc.DataSourceFactory
인스턴스를 XA 및 ConnectionPool 데이터 소스를 생성하는 것을 포함하여 구현되는 모든 메서드에 등록합니다.
전용 데이터베이스별 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
.DataSourcey 서비스를 등록합니다. 예를 들면 다음과 같습니다.
.ConnectionPoolDataSource
및 javax.sql.XADataSource
를 포함하여 모든 종류의 팩토리 를 반환할 수 있는 데이터베이스별 org.osgi.service.jdbc
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
서비스가 등록되어 지정된 데이터베이스의 데이터 소스를 가져올 수 있습니다( 6.2.1절. “데이터베이스 특정 및 일반 데이터 소스”참조). 그러나 실제 데이터 소스는 아직 없습니다.
mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.3.0
번들은 다음 두 가지 작업을 수행하는 관리형 서비스 팩토리를 제공합니다.
메서드를 호출하기 위해
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
파일을 생성하여 구성 관리 서비스에 사용할 수 있는 방법을 사용하여 팩토리 구성을 생성하는 경우 최종 단계를 수행하여 실제 데이터베이스별 데이터 소스를 노출할 수 있습니다.
다음은 새로운 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
중간
org.osgi.service.jdbc.DataSourceFactory
를 등록하는 OSGi JDBC 서비스 번들 및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)
org.osgi.service.jdbc.DataSourceFactory
서비스 및org.ops4j.datasource
factory PID 를 추적하는pax-jdbc
-config 번 들과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 = fuse
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. 처리된 속성 요약
admin 팩토리 PID 구성의 속성은 관련 org.osgi.service.jdbc.DataSourceFactory
구현으로 전달됩니다.
일반
org.ops4j.pax.jdbc.impl.DriverDataSourceFactory
properties:
-
url
-
user
-
암호
DB2
org.ops4j.pax.jdbc.db2.impl.DB2DataSourceFactory
속성에는 다음과 같은 구현 클래스의 모든 empty 속성이 포함됩니다.
-
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
-
암호
-
databaseName
모든 Cryostat 속성
-
org.hsqldb.jdbc.JDBCDataSource
-
org.hsqldb.jdbc.pool.JDBCPooledDataSource
-
org.hsqldb.jdbc.pool.JDBCXADataSource
-
SQL Server 및 Sybase
org.ops4j.pax.jdbc.jtds.jtds.jtds.JTDSDataFactory
속성에는 net.sourceforge.jtds.jdbcx.JtdsDataSource
.
SQL Server
org.ops4j.pax.jdbc.mssql.impl.MSSQLDataSourceFactory
properties:
-
url
-
user
-
암호
-
databaseName
-
serverName
-
portNumber
모든 Cryostat 속성
-
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
-
암호
-
databaseName
-
serverName
-
portNumber
모든 Cryostat 속성
-
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
-
암호
모든 Cryostat 속성
-
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
의 모든 Cryostat 속성
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.13.0.fuse-7_13_0-00012-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.createDataSourceSource(properties)
로 전달됩니다. 그러나 이러한 속성은 접두사가 제거되지 않고 (예: javax.sql.DataSource
OSGi 서비스) 속성으로 추가됩니다.