Always Free 環境で構築するグラフデータベース！

##本記事の目的
Always Free環境でOracle Autonomous Databaseに保存されているデータをグラフとして読み込み、Graph Vizで可視化するまでの手順をご紹介します。

##前提条件
 - Graph Server and Clientがダウンロード済みであること
 
まだダウンロードしていない方は[こちら](https://www.oracle.com/database/technologies/spatialandgraph/property-graph-features/graph-server-and-client/graph-server-and-client-downloads.html)からOracle Graph Server and Clientをダウンロードしてください。
インストール手順は[Document](https://docs.oracle.com/en/database/oracle/oracle-database/20/spgdg/property-graph-overview-spgdg.html#GUID-FF149F69-574D-43B8-B888-4CCD019DAE56)や[こちらの記事](https://qiita.com/kk31108424/items/699eb86616c9cbd52f0a)を参考にしてください。


##Always Free環境の構築
###Computeインスタンス作成

[こちら](https://qiita.com/xianon/items/199e6794160e2c6da911)の記事を参考に、仮想クラウドネットワーク・Computeの作成を行ってください。


###Autonomous Database作成

####インスタンス作成

ナビゲーション・メニュー > データベース > Autonomous Data Warehouseを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/d395967f-5678-2d6d-d1f8-3102f1d6d7e5.png)


「Autonomous Databaseを作成」ダイアログで以下の項目を入力します。

 - 基本データベース情報
    - 表示名
    - コンパートメント
    - Databaseの名前
 - ワークロードタイプ
    - Autonomous Data Warehouse または Autonomous Transaction Processing
 - データベースCPUコア数およびストレージの構成
    - Always Freeオプションを選択
 - 管理者資格証明
    - 以下の基準を満たすパスワードを入力
        - 12から30文字までの長さ
        - 1つ以上の小文字を含む
        - 少なくとも1つの大文字を含む
        - 少なくとも1つの番号が含む
        - 二重引用符( ")は含まない
        - 大/小文字に関係なく、文字列adminは含まない
 - ライセンス・タイプ
    - Always Freeの場合は調整不要

![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/c802b612-9cf2-f8ff-778d-9ca46df672d8.png)

 
上記の入力が終わったら、「Autonomous Databaseの作成」をクリックします。

![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/4333c32b-a5e2-1f80-cfba-be7e880ea7b6.png)

プロビジョニングが完了すると、下記のように緑色のマークに変化します。

![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/13182778-9289-c926-595d-aaf9f4f54bdd.png)


####walletファイルダウンロード



``DB接続``をクリックします。

![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/6d15cfd7-9371-ad5d-1382-60d7653975c9.png)

下記の画面から、``ウォレットのダウンロード``をクリックし、ウォレットをダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/9f68851a-4e79-2bec-de9f-58be9dcdb05c.png)

**ダウンロードしたウォレットは、作成したComputeインスタンスの任意のディレクトリに解凍しておきましょう。**


####今回使用するサンプルデータ作成

SQL Developer Webから、今回使用するサンプルデータを作成します。

``サービスコンソール`` > ``SQL Developer Web``をクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/e5c1ffb8-1be8-13df-3d5a-681efd756307.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/1c61f2e0-7846-bda5-66f8-2004d2647416.png)

以下を指定してログインします。
 - ユーザー名 : `ADMIN`
 - パスワード : `Autonomous Database作成時に指定したパスワード`

![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/061ab598-cd38-e563-d5c9-b2cdf5f29f9a.png)

ログイン完了後、以下のSQLで今回使用するスキーマを作成し、権限を付与します。

```sql
CREATE USER customer_360 IDENTIFIED BY pass;
GRANT CREATE SESSION to customer_360;
GRANT CREATE TABLE to customer_360;
GRANT ALTER SESSION to customer_360;
GRANT ALTER ANY TABLE to customer_360;
```

Autonomous Databaseに、サンプルグラフで使用するデータをあらかじめロードしておきます。
ロード時のスクリプトは、[こちら](https://github.com/ryotayamanaka/oracle-pg/blob/master/graphs/customer_360/create_tables.sql)を参照して下さい。

##Two-TierとThree-Tierの違い

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/7bb75632-2089-04c8-911d-ef9c0c41a288.png)

アーキテクチャの観点では、``Two-Tierモード``と``Three-Tierモード``の2種類があります。

 - ``Two-Tierモード``
Graph Clientとなるアプリケーションが直接Oracle Databaseに接続する構成です。

 - ``Three-Tierモード``
Graph ClientとなるアプリケーションはGraph Serverに接続し、仲介するGraph ServerがOracle Databaseに接続します。
 
##グラフデータベース作成手順（Two-Tier / Three-Tier 共通）
以下の作業は全て作成したComputeインスタンスにて行ってください。

###1. opg-rdbms-jshell起動

```
opg-jshell-rdbms> var jdbcUrl = "jdbc:oracle:thin:@<tnsnames.ora内の接続記述子>?TNS_ADMIN=<Walletファイルを解凍したディレクトリを指定>"
```

実行例

```
opg-jshell-rdbms> var jdbcUrl = "jdbc:oracle:thin:@db201901151442_low?TNS_ADMIN=/etc/wallet"
```

###2. jdbc connection, user, password定義

```
opg-jshell-rdbms> var user = "<DB Username>"
user ==> "○○○"
opg-jshell-rdbms> var pass = "<DB User Password>"
pass ==> "△△△"
```

実行例

```
opg-jshell-rdbms> var user = "customer_360"
user ==> "customer_360"
opg-jshell-rdbms> var pass = "Welcome1"
pass ==> "Welcome1"
```


###3. DriverManager.getConnectionで接続

```
opg-jshell-rdbms> var conn = DriverManager.getConnection(jdbcUrl, user, pass)
conn ==> oracle.jdbc.driver.T4CConnection@6d484bf4
```

###4. Graph Clientからグラフを作成

以下のPGQLを記載したファイルを作成します。
（今回は、``/opt/oracle/graph/graph_data/create_pg.pgql``に作成します。）

```:/opt/oracle/graph/graph_data/create_pg.pgql
CREATE PROPERTY GRAPH customer_360
    VERTEX TABLES(
        customer
            LABEL "customer"
            PROPERTIES(
                type as "type"
               ,name as "name"
               ,age as "age"
               ,location as "location"
               ,gender as "gender"
               ,student as "student"
               )
       ,account
            LABEL "account"
            PROPERTIES(
                type as "type"
               ,account_no as "account_no"
               ,balance as "balance"
               )
       ,merchant
            LABEL "merchant"
            PROPERTIES(
                type as "type"
               ,name as "name"
               )
       )
    EDGE TABLES(
        owned_by
            SOURCE KEY(from_id) REFERENCES account
            DESTINATION KEY(to_id) REFERENCES customer 
            LABEL "owned_by" 
            PROPERTIES ( 
                since AS "since" 
            ) 
       ,parent_of 
            SOURCE KEY(from_id) REFERENCES customer 
            DESTINATION KEY(to_id) REFERENCES customer 
            LABEL "parent_of" 
       ,purchased 
            SOURCE KEY(from_id) REFERENCES account 
            DESTINATION KEY(to_id) REFERENCES merchant 
            LABEL "purchased" 
            PROPERTIES ( 
                amount AS "amount" 
            ) 
       ,transfer 
            SOURCE KEY(from_id) REFERENCES account 
            DESTINATION KEY(to_id) REFERENCES account 
            LABEL "transfer" 
            PROPERTIES ( 
                amount AS "amount" 
              , date AS "date" 
            ) 
      ) 
```

作成したpgqlファイルをjshellで読み込み、PQGLを実行します。

```
opg-jshell-rdbms> conn.setAutoCommit(false)
opg-jshell-rdbms> var pgql = PgqlConnection.getConnection(conn)
opg-jshell-rdbms> pgql.prepareStatement(Files.readString(Paths.get("/opt/oracle/graph/graph_data/create_pg.pgql"))).execute()
opg-jshell-rdbms>　Consumer<String> query = q -> {
  try(var s = pgql.prepareStatement(q)){
    s.execute();
    s.getResultSet().print();
 }catch(Exception e){
    throw new RuntimeException(e);
 }
}
opg-jshell-rdbms>　query.accept("select count(v) from customer_360 match(v)");
```

件数が返ってくれば成功です。

##グラフデータベース作成手順（Three-Tierで使用する場合の追加手順）

###5. Databaseのパスワードを含んだJava Keystore作成

```
$ keytool -importpass -alias nwpg -keystore nwpgkeystore.p12 -storetype pkcs12
キーストアのパスワードを入力してください: <Keystoreのパスワードを入力>  
保存するパスワードを入力してください:  <保存するパスワードを入力>
パスワードを再入力してください: <保存するパスワードを再入力>
```

Java 8 以前のJDKを使用している場合は、``-storetype pkcs12``オプションが必要です。

###6. JVMに``TNS_ADMIN``環境変数をオーバーライドして読み込ませるように設定

```
$ export JAVA_OPTS=“-Doracle.net.tns_admin=<ダウンロードしたウォレットを展開したディレクトリ> -Doracle.jdbc.fanEnabled=false”
```
実行例

```
$ export JAVA_OPTS=“-Doracle.net.tns_admin=/home/oracle/wallet -Doracle.jdbc.fanEnabled=false”
```

###7. 手順５で作成したJava Keystoreを指定してGraph Serverを起動
```
$ cd /opt/oracle/graph
$ ./pgx/bin/start-server --secret-store /home/oracle/wallet/nwpgkeystore.p12
```

###8. Graph Vizで可視化

 - ``http://<サーバのIPアドレス>:7007/ui`` に接続
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248756/37c596e3-5779-1e5c-7441-e636ddf6e1f2.png)

Autonomous Databaseからグラフをロードできました！

##まとめ

今回は、Autonomous Databaseに保存されているデータを用いてグラフを作成しました。
サポート範囲が広がってきているPGXを活用して、どんどんネットワーク分析をしましょう！

（本記事は、@mtc465、@eyebmah0 の協力のもと執筆しました。）