Autonomous DB(ADW/ATP) に Java の JDBC Thin Driver で接続してみる。(OCI, Oracle Cloud Infrastructure)

表題の通り、Autonomous DB(ADW/ATP) に Java の JDBC Thin Driver で
接続してみます。下記の構成で試すやで彡(ﾟ)(ﾟ)

 > Compute(Java, JDBC Thin Driver) ⇒ Autonomous DB(ADW/ATP)

前回の記事の続きになります。

 > OCI Database(DBaaS) の PDB に Java の JDBC Thin Driver で
 > 接続してみる。(Oracle Cloud Infrastructure)
 > https://qiita.com/ora_gonsuke777/items/0e6c7d25d9977de45531

# 1. Autonomous DB(ADW/ATP) とは？

Autonomous DB は ORACLE が提供する Full Managed なデータベースの Cloud Service です。

DWH向きの ADW(Autonomous Data Warehouse) と
OLTP向きの ATP(Autonomous Transaction Processing) が有るんやで彡(ﾟ)(ﾟ)

 > Autonomous Data Warehouse
 > https://docs.oracle.com/cd/E83857_01/paas/autonomous-data-warehouse-cloud/
 >  
 > Autonomous Transaction Processing
 > https://docs.oracle.com/cd/E83857_01/paas/atp-cloud/

# 2. Autonomous DB(ADW/ATP) に接続する時のポイント(※ウォレットが必須)

通常のOracle Databaseへの接続 と Autonomous DB(ADW/ATP)への接続 の違いとして、
ウォレットによる暗号化通信が必須である点が挙げられます。

 > Autonomous Data Warehouse Instanceへの接続について
 > https://docs.oracle.com/cd/E83857_01/paas/autonomous-data-warehouse-cloud/user/connect-intorduction.html#GUID-CD4C10A6-1C1E-4969-8F67-1433B6CE626A
 > 
 > Autonomous Transaction Processing Instanceへの接続について
 > https://docs.oracle.com/cd/E83857_01/paas/atp-cloud/atpug/connect-intorduction.html#GUID-CD4C10A6-1C1E-4969-8F67-1433B6CE626A

sqlplus や SQL Developer での接続については下記マニュアルを参照彡(ﾟ)(ﾟ)

 > Oracle SQL Developer (18.2)以上で接続
 > https://docs.oracle.com/cd/E83857_01/paas/autonomous-data-warehouse-cloud/user/connect-sql-dev182.html#GUID-14217939-3E8F-4782-BFF2-021199A908FD
 > 
 > Connect with SQL*Plus
 > https://docs.oracle.com/cd/E83857_01/paas/autonomous-data-warehouse-cloud/user/connect-sqlplus.html#GUID-A3005A6E-9ECF-40CB-8EFC-D1CFF664EC5A

何かしらの手段でウォレットを指定する事が、ADW/ATP接続の必須事項となります。
本記事では JDBC Thin driver + TNS_ADMIN による接続を幾つか試してみますやで彡(ﾟ)(ﾟ)

# 3. ウォレット、JDBC Driver Full版 のダウンロードと展開

手順は幾つか有りますが、下記マニュアルの「Plain JDBC using Oracle Wallets」を実行します。

 > Java Connectivity with Autonomous Database (ATP or ADW) using 18.3 JDBC
 > https://www.oracle.com/technetwork/database/application-development/jdbc/documentation/atp-5073445.html

ウォレットのダウンロードと展開は下記が参考になります。

 > 自律型データベース(Autonomous Transaction Processing)に Golang を使って接続
 > https://qiita.com/sugimount/items/69e11c116a895c9feb97

```sh
# Autonomous DB の Wallet を展開
unzip Wallet_xxxxxx.zip
```

JDBC Driver の最新版(18.3)は現時点(2019/2/26)で下記ですが、最新版を参照して下さい。

 > Oracle Database 18c (18.3) JDBC Driver & UCP Downloads
 > https://www.oracle.com/technetwork/database/application-development/jdbc/downloads/jdbc-ucp-183-5013470.html

ojdbc8-full.tar.gz をダウンロードして、Compute上に展開(tar xvzf ～)します。

```sh
# JDBC Driver Full版を展開
tar xvzf ojdbc8-full.tar.gz
```

ウォレットは/home/opc/app/opc/product/18.0.0/client_1/network/adminに、
JDBC Driver は/home/opc/work/ojdbc8-full にそれぞれ展開したものとします。

```sh
# Wallet(TNS_ADMIN)
ls -la /home/opc/app/opc/product/18.0.0/client_1/network/admin

total 76
drwxr-xr-x.  3 opc opc  4096 Feb 25 16:26 .
drwxr-xr-x. 10 opc opc  4096 Jan 17 06:46 ..
-rw-rw-r--.  1 opc opc  6661 Feb 25 15:01 cwallet.sso
-rw-rw-r--.  1 opc opc  6616 Feb 25 15:01 ewallet.p12
-rw-rw-r--.  1 opc opc  3242 Feb 25 15:01 keystore.jks
-rw-rw-r--.  1 opc opc    87 Feb 25 15:01 ojdbc.properties
drwxr-xr-x.  2 opc opc  4096 Jan 17 06:44 samples
-rw-r--r--.  1 opc opc  1441 Aug 26  2015 shrept.lst
-rw-rw-r--.  1 opc opc   114 Feb 25 15:01 sqlnet.ora
-rw-rw-r--.  1 opc opc   155 Feb  4 11:23 sqlnet.ora.bak
-rw-rw-r--.  1 opc opc  2771 Feb 25 15:01 tnsnames.ora
-rw-rw-r--.  1 opc opc  3336 Feb 25 15:01 truststore.jks
-rw-rw-r--.  1 opc opc 19823 Feb 25 15:01 Wallet_xxxxxx.zip

# JDBC Driver full
ls -la /home/opc/work/ojdbc8-full

total 8328
drwx------.  2 opc opc    4096 Aug 20  2018 .
drwxrwxr-x. 22 opc opc    4096 Feb 25 15:33 ..
-r--r--r--.  1 opc opc 4161744 Aug  2  2018 ojdbc8.jar
-r-xr-xr-x.  1 opc opc   11596 Aug  2  2018 ojdbc.policy
-r--r--r--.  1 opc opc  144428 Aug  2  2018 ons.jar
-r--r--r--.  1 opc opc  307817 Aug  2  2018 oraclepki.jar
-r--r--r--.  1 opc opc 1661545 Aug  2  2018 orai18n.jar
-r--r--r--.  1 opc opc  205152 Aug  2  2018 osdt_cert.jar
-r--r--r--.  1 opc opc  306854 Aug  2  2018 osdt_core.jar
-rw-r--r--.  1 opc opc    2595 Aug 20  2018 README.txt
-r--r--r--.  1 opc opc   29103 Aug  2  2018 simplefan.jar
-r--r--r--.  1 opc opc 1398331 Aug  2  2018 ucp.jar
-r--r--r--.  1 opc opc  262415 Aug  2  2018 xdb6.jar
```

# 4. 方法1:ウォレットのパス(TNS_ADMIN) を JDBC URL に記述

JDBC 18.3 では ウォレットのパスを TNS_ADMIN として
JDBC URL に記述できるようになっています。

 > URLに指定されています。 次に例を示します。
 > https://docs.oracle.com/cd/E83857_01/paas/atp-cloud/atpug/connect-jdbc-thin-wallet.html#GUID-F1D7452F-5E67-4418-B16B-B6A7B92F26A4
 > final static String DB_URL="jdbc:oracle:thin:@atpconnection_low?TNS_ADMIN=.";

この書き方の場合、接続文字列はtnsnames.oraの記述子を使用します。サンプルは下記

```java
import java.sql.*;

public class GetContainerName {
    public static void main(String[] args) {
        final String path = "jdbc:oracle:thin:@xxxxxx_high?TNS_ADMIN=/home/opc/app/opc/product/18.0.0/client_1/network/admin";
        final String id = "ADMIN";  //ID
        final String pw = "xxxxxxxxxxxxx";  //password

        try (
            Connection conn = DriverManager.getConnection(path, id, pw);
            Statement  stmt = conn.createStatement();
            ResultSet  rs   = stmt.executeQuery("SELECT NAME FROM V$CONTAINERS");
        ) {
            while (rs.next()) {
                String cn = rs.getString("name");
                System.out.println("Container Name => " + cn);
            }
        } catch(SQLException ex) {
            ex.printStackTrace();  //Error
        }
    }
}
```

コンパイルと実行は下記。[マニュアル](https://docs.oracle.com/cd/E83857_01/paas/atp-cloud/atpug/connect-jdbc-thin-wallet.html#GUID-F1D7452F-5E67-4418-B16B-B6A7B92F26A4)の記述の通り oraclepki.jar, 
osdt_core.jar, osdt_cert.jarを classpath に含めておくんやで彡(ﾟ)(ﾟ)

```sh
export JAVA_HOME=/home/opc/work/jdk-11.0.2
export PATH=${JAVA_HOME}/bin:${PATH}

javac GetContainerName.java

java -classpath /home/opc/work/ojdbc8-full/ojdbc8.jar:\
/home/opc/work/ojdbc8-full/ucp.jar:\
/home/opc/work/ojdbc8-full/oraclepki.jar:\
/home/opc/work/ojdbc8-full/osdt_core.jar:\
/home/opc/work/ojdbc8-full/osdt_cert.jar:. \
GetContainerName

Container Name => VRWV9351YZ4NXNS_XXXXXX
```

成功(｀･ω･)Ъ

# 5. 方法2:ウォレットのパス(TNS_ADMIN) を 環境変数に指定

ウォレットのパスをTNS_ADMIN環境変数に指定します。
この場合は JDBC URL に TNS_ADMIN の記述は不要で、ソースは下記彡(ﾟ)(ﾟ)

```java
import java.sql.*;

public class GetContainerName {
    public static void main(String[] args) {
        final String path = "jdbc:oracle:thin:@xxxxxx_high";
        final String id = "ADMIN";  //ID
        final String pw = "xxxxxxxxxxxxx";  //password

        try (
            Connection conn = DriverManager.getConnection(path, id, pw);
            Statement  stmt = conn.createStatement();
            ResultSet  rs   = stmt.executeQuery("SELECT NAME FROM V$CONTAINERS");
        ) {
            while (rs.next()) {
                String cn = rs.getString("name");
                System.out.println("Container Name => " + cn);
            }
        } catch(SQLException ex) {
            ex.printStackTrace();  //Error
        }
    }
}
```

コンパイルと実行結果は以下の通りです。

```sh
export JAVA_HOME=/home/opc/work/jdk-11.0.2
export PATH=${JAVA_HOME}/bin:${PATH}

javac GetContainerName.java

export TNS_ADMIN=/home/opc/app/opc/product/18.0.0/client_1/network/admin

java -classpath /home/opc/work/ojdbc8-full/ojdbc8.jar:\
/home/opc/work/ojdbc8-full/ucp.jar:\
/home/opc/work/ojdbc8-full/oraclepki.jar:\
/home/opc/work/ojdbc8-full/osdt_core.jar:\
/home/opc/work/ojdbc8-full/osdt_cert.jar:. \
GetContainerName

Container Name => VRWV9351YZ4NXNS_XXXXXX
```

再び成功(｀･ω･)Ъ

# 6. 方法3:ウォレットのパス(TNS_ADMIN) を -D でシステム・プロパティとして指定

ウォレットのパスをシステム・プロパティoracle.net.tns_admin として
-Dオプションで指定します。javaソースは上記 5. と同じなので省略。

実行コマンドは下記となります。

```sh
export JAVA_HOME=/home/opc/work/jdk-11.0.2
export PATH=${JAVA_HOME}/bin:${PATH}

javac GetContainerName.java

unset TNS_ADMIN

java -classpath /home/opc/work/ojdbc8-full/ojdbc8.jar:\
/home/opc/work/ojdbc8-full/ucp.jar:\
/home/opc/work/ojdbc8-full/oraclepki.jar:\
/home/opc/work/ojdbc8-full/osdt_core.jar:\
/home/opc/work/ojdbc8-full/osdt_cert.jar:. \
-Doracle.net.tns_admin=/home/opc/app/opc/product/18.0.0/client_1/network/admin \
GetContainerName

Container Name => VRWV9351YZ4NXNS_XXXXXX
```

三たび成功(｀･ω･)Ъ

#7. まとめ

oraclepki.jar, osdt_core.jar, osdt_cert.jar の classpath指定で
くっそハマった……まずはマニュアルの通りにやるのが、王道ですやね彡(-)(-)