NablarchのRESTfulウェブサービスのExampleをPostgreSQLを使うように変更してみる

# What's？

Nablarchのサンプルといえば、GitHub上に各種Exampleが公開されています。

[https://github.com/orgs/nablarch/repositories?language=&q=example&sort=&type=all](https://github.com/orgs/nablarch/repositories?language=&q=example&sort=&type=all)

これらのExampleはデータベースがH2なのですが、他のRDBMSを扱う際に手っ取り早くアプリケーションを扱うにはこのExampleが最も近いので、こちらを他のRDBMSを使うように変更するようにしてみました。

対象は、RESTfulウェブサービスのExampleとします。

https://github.com/nablarch/nablarch-example-rest

ちなみにですが、Exampleには以下の注意点があります。

> ExampleはNablarchの機能の利用方法を示した実装例であり、Exampleを改修して本格的なアプリケーションを作成することは想定していない。
>
> 本格的なアプリケーションを作成する場合は ブランクプロジェクト から作成すること。

https://nablarch.github.io/docs/5u21/doc/application_framework/application_framework/web_service/rest/getting_started/index.html

今回は、あくまで「手っ取り早くアプリケーションが欲しい」という目的のために使います。

# 環境

今回の環境は、こちら。

```shell
$ java --version
openjdk 11.0.16 2022-07-19
OpenJDK Runtime Environment (build 11.0.16+8-post-Ubuntu-0ubuntu120.04)
OpenJDK 64-Bit Server VM (build 11.0.16+8-post-Ubuntu-0ubuntu120.04, mixed mode, sharing)


$ mvn --version
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Maven home: /home/charon/.sdkman/candidates/maven/current
Java version: 11.0.16, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-126-generic", arch: "amd64", family: "unix"
```

使用するNablarchは、5u21とします。

PostgreSQLについては、Dockerで用意。

```shell
$ docker container run -it --rm -p 5432:5432 \
  -e POSTGRES_DB=rest_example \
  -e POSTGRES_USER=rest_example \
  -e POSTGRES_PASSWORD=rest_example \
  --name postgres \
  postgres:14.5
```

今回はNablarchのRESTfulウェブサービスのExampleを、上記のコマンドで起動したPostgreSQLを利用するように変更することをゴールにします。

なお、テーブル定義はObjectBrowser ERによるファイルで作成されていますが、今回はそのまま利用できました。

https://github.com/nablarch/nablarch-example-rest/blob/5u21/src/main/resources/entity/data-model.edm

# nablarch-example-restリポジトリのclone

まずはnablarch-example-restリポジトリをクローン。

```shell
$ git clone https://github.com/nablarch/nablarch-example-rest.git
```

利用するNablarchのバージョン（5u21）にタグを合わせておきます。

```shell
$ cd nablarch-example-rest
$ git checkout 5u21
```

# Java 11に対応させる

いきなり脱線しますが、nablarch-example-restリポジトリはJava 8を前提にしているので、以下の手順に従ってJava 11に対応させましょう。

https://nablarch.github.io/docs/5u21/doc/application_framework/application_framework/blank_project/setup_blankProject/setup_Java11.html

`pom.xml`まわりから。

コンパイラの設定変更。

```xml:pom.xml
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
```

依存関係の追加。

```xml:pom.xml
    <!-- Java 11向け -->
    <dependency>
      <groupId>com.sun.activation</groupId>
      <artifactId>javax.activation</artifactId>
      <version>1.2.0</version>
    </dependency>
    <dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api</artifactId>
      <version>2.3.0</version>
    </dependency>
    <dependency>
      <groupId>com.sun.xml.bind</groupId>
      <artifactId>jaxb-core</artifactId>
      <version>2.3.0</version>
    </dependency>
    <dependency>
      <groupId>com.sun.xml.bind</groupId>
      <artifactId>jaxb-impl</artifactId>
      <version>2.3.0</version>
    </dependency>
    <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>javax.annotation-api</artifactId>
      <version>1.3.2</version>
    </dependency>
```

gsp-dba-maven-pluginの依存関係にも追加。

```xml:pom.xml
          <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>javax.activation-api</artifactId>
            <version>1.2.0</version>
          </dependency>
          <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
          </dependency>
          <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0</version>
          </dependency>
          <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
          </dependency>
          <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
          </dependency>
```

テスティングフレームワークのJettyのバージョンも変更します。

```xml:pom.xml
    <dependency>
      <groupId>com.nablarch.framework</groupId>
      <artifactId>nablarch-testing-jetty9</artifactId>
      <scope>test</scope>
    </dependency>
```

テストのコンポーネント定義も変更。

```xml:src/test/resources/unit-test.xml
  <!-- テスト用HttpServerにJetty9を定義する -->
  <component name="httpServerFactory" class="nablarch.fw.web.httpserver.HttpServerFactoryJetty9"/>
```

テストを実行して、動作確認しておきましょう。

```shell
$ mvn test
```

```shell
[INFO] Results:
[INFO]
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
```

この時点ではH2を使っているので、1度削除しておきます。

```shell
$ rm -rf h2
$ mvn clean
```

# 使用するデータベースをH2からPostgreSQLに変更する

次に、使用するデータベースをPostgreSQLに変更します。

依存関係に含まれているH2のJDBCドライバを、PostgreSQLのJDBCドライバに変更。

```xml:pom.xml
    <dependency>
      <groupId>org.postgresql</groupId>
      <artifactId>postgresql</artifactId>
      <version>42.5.0</version>
      <scope>runtime</scope>
    </dependency>
```

`env.properties`に記載されている、接続設定も変更。

```properties:src/main/resources/env.properties
# JDBC接続ドライバクラス(DataSourceを直接使用する際の項目)
nablarch.db.jdbcDriver=org.postgresql.Driver

# JDBC接続URL(DataSourceを直接使用する際の項目)
nablarch.db.url=jdbc:postgresql://localhost:5432/rest_example?ApplicationName=rest

# DB接続ユーザ名(DataSourceを直接使用する際の項目)
nablarch.db.user=rest_example

# DB接続パスワード(DataSourceを直接使用する際の項目)
nablarch.db.password=rest_example

# DBスキーマ名(DataSourceを直接使用する際の項目)
nablarch.db.schema=public
```

JDBC接続URLには、なんとなく`ApplicationName`を含めておきました。

Dialectの設定を変更します。

```xml:src/main/resources/rest-component-configuration.xml
  <!-- ダイアレクト設定 -->
  <component name="dialect" class="nablarch.core.db.dialect.PostgreSQLDialect" />
```

[データベースアクセス(JDBCラッパー) / 使用方法 / データベース製品に対応したダイアレクトを使用する](https://nablarch.github.io/docs/5u21/doc/application_framework/application_framework/libraries/database/database.html#database-use-dialect)

gsp-dba-maven-pluginの依存関係に含まれている、H2のJDBCドライバもPostgreSQLのものに変更します。

```xml:pom.xml
          <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.5.0</version>
            <scope>runtime</scope>
          </dependency>
```

接続先に関する定義も変更しておきます。

```xml:pom.xml
    <db.adminUser>rest_example</db.adminUser>
    <db.user>rest_example</db.user>
```

```xml:pom.xml
          <driver>org.postgresql.Driver</driver>          <url>jdbc:postgresql://localhost:5432/rest_example?ApplicationName=gsp-dba-maven-plugin</url>

          <adminUser>${db.adminUser}</adminUser>
          <adminPassword>${db.adminUser}</adminPassword>
          <user>${db.user}</user>
          <password>${db.user}</password>
          <schema>public</schema>
```

これで、変更完了です。

# 動作確認

まずはテストを動かしてみましょう。

```shell
$ mvn test
```

OKでした。

```shell
[INFO] Results:
[INFO]
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
```

PostgreSQLに対してテーブルの作成やデータの登録ができているか、確認してみます。

```shell
$ docker container exec -it postgres psql -U rest_example
psql (14.5 (Debian 14.5-1.pgdg110+1))
Type "help" for help.

rest_example=#
```

こちらもOKですね。

```sql
rest_example=# \d
                       List of relations
 Schema |            Name            |   Type   |    Owner
--------+----------------------------+----------+--------------
 public | client                     | table    | rest_example
 public | client_client_id_seq       | sequence | rest_example
 public | industry                   | table    | rest_example
 public | password_history           | table    | rest_example
 public | project                    | table    | rest_example
 public | project_project_id_seq     | sequence | rest_example
 public | system_account             | table    | rest_example
 public | system_account_user_id_seq | sequence | rest_example
 public | users                      | table    | rest_example
(9 rows)

rest_example=# select * from client limit 5;
 client_id | client_name | industry_code
-----------+-------------+---------------
         1 | １株式会社  | 26
         2 | ２株式会社  | 26
         3 | ３株式会社  | 26
         4 | ４株式会社  | 26
         5 | ５株式会社  | 26
(5 rows)

```

最後に、ふつうにアプリケーションを起動してみましょう。

```shell
$ mvn compile waitt:run-headless
```

確認。

```shell
$ curl -s localhost:9080/projects | jq
[
  {
    "projectId": 1,
    "projectName": "プロジェクト００１",
    "projectType": "development",
    "projectClass": "s",
    "projectStartDate": "2010/09/18",
    "projectEndDate": "2015/04/09",
    "clientId": 1,
    "projectManager": "鈴木",
    "projectLeader": "佐藤",
    "userId": 100,
    "note": "備考欄",
    "sales": 10000,
    "costOfGoodsSold": 1000,
    "sga": 2000,
    "allocationOfCorpExpenses": 3000,
    "client": null,
    "systemAccount": null
  },
  {
    "projectId": 2,
    "projectName": "プロジェクト００２",
    "projectType": "maintenance",
    "projectClass": "b",
    "projectStartDate": "2010/09/18",
    "projectEndDate": "2014/11/10",
    "clientId": 2,
    "projectManager": "佐藤",
    "projectLeader": "鈴木",
    "userId": 100,
    "note": null,
    "sales": null,
    "costOfGoodsSold": null,
    "sga": null,
    "allocationOfCorpExpenses": null,
    "client": null,
    "systemAccount": null
  },
  {
    "projectId": 3,
    "projectName": "プロジェクト００３",
    "projectType": "development",
    "projectClass": "c",
    "projectStartDate": "2015/04/09",
    "projectEndDate": "2015/04/09",
    "clientId": 3,
    "projectManager": "田中",
    "projectLeader": "佐藤",
    "userId": 100,
    "note": "空白",
    "sales": 10000,
    "costOfGoodsSold": 1000,
    "sga": 2000,
    "allocationOfCorpExpenses": 3000,
    "client": null,
    "systemAccount": null
  },
  {
    "projectId": 4,
    "projectName": "プロジェクト００４",
    "projectType": "development",
    "projectClass": "a",
    "projectStartDate": "2012/06/22",
    "projectEndDate": "2013/04/01",
    "clientId": 4,
    "projectManager": "山田",
    "projectLeader": "田中",
    "userId": 100,
    "note": "なし",
    "sales": 10000,
    "costOfGoodsSold": 1000,
    "sga": 2000,
    "allocationOfCorpExpenses": 3000,
    "client": null,
    "systemAccount": null
  },
  {
    "projectId": 5,
    "projectName": "プロジェクト００５",
    "projectType": "maintenance",
    "projectClass": "ss",
    "projectStartDate": "2012/12/01",
    "projectEndDate": "2014/12/31",
    "clientId": 5,
    "projectManager": "鈴木",
    "projectLeader": "山田",
    "userId": 100,
    "note": "テスト",
    "sales": 10000,
    "costOfGoodsSold": 1000,
    "sga": 2000,
    "allocationOfCorpExpenses": 3000,
    "client": null,
    "systemAccount": null
  },
  {
    "projectId": 6,
    "projectName": "プロジェクト００６",
    "projectType": "maintenance",
    "projectClass": "d",
    "projectStartDate": "2012/06/22",
    "projectEndDate": "2015/01/08",
    "clientId": 6,
    "projectManager": "佐藤",
    "projectLeader": "鈴木",
    "userId": 100,
    "note": null,
    "sales": 10000,
    "costOfGoodsSold": 1000,
    "sga": 2000,
    "allocationOfCorpExpenses": 3000,
    "client": null,
    "systemAccount": null
  },
  {
    "projectId": 7,
    "projectName": "プロジェクト００７",
    "projectType": "development",
    "projectClass": "s",
    "projectStartDate": "2012/12/01",
    "projectEndDate": "2015/04/09",
    "clientId": 7,
    "projectManager": "鈴木",
    "projectLeader": "佐藤",
    "userId": 100,
    "note": "備考欄１",
    "sales": 10000,
    "costOfGoodsSold": 1000,
    "sga": 2000,
    "allocationOfCorpExpenses": 3000,
    "client": null,
    "systemAccount": null
  },
  {
    "projectId": 8,
    "projectName": "プロジェクト００８",
    "projectType": "development",
    "projectClass": "s",
    "projectStartDate": "2010/09/18",
    "projectEndDate": "2014/11/10",
    "clientId": 8,
    "projectManager": "佐藤",
    "projectLeader": "佐藤",
    "userId": 100,
    "note": "備考欄２",
    "sales": 10000,
    "costOfGoodsSold": 1000,
    "sga": 2000,
    "allocationOfCorpExpenses": 3000,
    "client": null,
    "systemAccount": null
  },
  {
    "projectId": 9,
    "projectName": "プロジェクト００９",
    "projectType": "development",
    "projectClass": "b",
    "projectStartDate": "2015/04/09",
    "projectEndDate": "2015/04/09",
    "clientId": 9,
    "projectManager": "田中",
    "projectLeader": "鈴木",
    "userId": 100,
    "note": "備考欄３",
    "sales": 10000,
    "costOfGoodsSold": 1000,
    "sga": 2000,
    "allocationOfCorpExpenses": 3000,
    "client": null,
    "systemAccount": null
  },
  {
    "projectId": 10,
    "projectName": "プロジェクト０１０",
    "projectType": "maintenance",
    "projectClass": "c",
    "projectStartDate": "2012/06/22",
    "projectEndDate": "2013/04/01",
    "clientId": 10,
    "projectManager": "山田",
    "projectLeader": "佐藤",
    "userId": 100,
    "note": "備考欄４",
    "sales": 10000,
    "costOfGoodsSold": 1000,
    "sga": 2000,
    "allocationOfCorpExpenses": 3000,
    "client": null,
    "systemAccount": null
  }
]
```

これで、NablarchのRESTfulウェブサービスのExampleをPostgreSQLを使うように変更できました。

# 変更差分

最後に、今回の内容で変更したファイルの差分を載せておきます。

```xml
$ git diff
diff --git a/pom.xml b/pom.xml
index f5b9a78..dc8e8ec 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,14 +9,14 @@
   <packaging>war</packaging>

   <properties>
-    <maven.compiler.source>1.8</maven.compiler.source>
-    <maven.compiler.target>1.8</maven.compiler.target>
+    <maven.compiler.source>11</maven.compiler.source>
+    <maven.compiler.target>11</maven.compiler.target>

     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

-    <db.adminUser>REST_EXAMPLE</db.adminUser>
-    <db.user>REST_EXAMPLE</db.user>
+    <db.adminUser>rest_example</db.adminUser>
+    <db.user>rest_example</db.user>

   </properties>

@@ -72,7 +72,7 @@
     </dependency>
     <dependency>
       <groupId>com.nablarch.framework</groupId>
-      <artifactId>nablarch-testing-jetty6</artifactId>
+      <artifactId>nablarch-testing-jetty9</artifactId>
       <scope>test</scope>
     </dependency>

@@ -118,9 +118,9 @@
     </dependency>

     <dependency>
-      <groupId>com.h2database</groupId>
-      <artifactId>h2</artifactId>
-      <version>1.4.196</version>
+      <groupId>org.postgresql</groupId>
+      <artifactId>postgresql</artifactId>
+      <version>42.5.0</version>
       <scope>runtime</scope>
     </dependency>

@@ -161,6 +161,33 @@
       <version>2.29.1</version>
     </dependency>

+    <!-- Java 11向け -->
+    <dependency>
+      <groupId>com.sun.activation</groupId>
+      <artifactId>javax.activation</artifactId>
+      <version>1.2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.xml.bind</groupId>
+      <artifactId>jaxb-api</artifactId>
+      <version>2.3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.xml.bind</groupId>
+      <artifactId>jaxb-core</artifactId>
+      <version>2.3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.xml.bind</groupId>
+      <artifactId>jaxb-impl</artifactId>
+      <version>2.3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.annotation</groupId>
+      <artifactId>javax.annotation-api</artifactId>
+      <version>1.3.2</version>
+    </dependency>
+
     <dependency>
       <groupId>org.glassfish.jersey.core</groupId>
       <artifactId>jersey-client</artifactId>
@@ -209,14 +236,14 @@
         <configuration>
           <erdFile>src/main/resources/entity/data-model.edm</erdFile>

-          <driver>org.h2.Driver</driver>
-          <url>jdbc:h2:./h2/db/rest_example</url>
+          <driver>org.postgresql.Driver</driver>
+          <url>jdbc:postgresql://localhost:5432/rest_example?ApplicationName=gsp-dba-maven-plugin</url>

           <adminUser>${db.adminUser}</adminUser>
           <adminPassword>${db.adminUser}</adminPassword>
           <user>${db.user}</user>
           <password>${db.user}</password>
-          <schema>PUBLIC</schema>
+          <schema>public</schema>

           <rootPackage>com.nablarch.example</rootPackage>
           <entityPackageName>entity</entityPackageName>
@@ -227,11 +254,36 @@
         </configuration>
         <dependencies>
           <dependency>
-            <groupId>com.h2database</groupId>
-            <artifactId>h2</artifactId>
-            <version>1.4.196</version>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>42.5.0</version>
             <scope>runtime</scope>
           </dependency>
+          <dependency>
+            <groupId>javax.activation</groupId>
+            <artifactId>javax.activation-api</artifactId>
+            <version>1.2.0</version>
+          </dependency>
+          <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <version>2.3.0</version>
+          </dependency>
+          <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-core</artifactId>
+            <version>2.3.0</version>
+          </dependency>
+          <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-impl</artifactId>
+            <version>2.3.0</version>
+          </dependency>
+          <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+            <version>1.3.2</version>
+          </dependency>
         </dependencies>
         <executions>
           <execution>
diff --git a/src/main/resources/env.properties b/src/main/resources/env.properties
index 2dee20f..074c8b5 100644
--- a/src/main/resources/env.properties
+++ b/src/main/resources/env.properties
@@ -3,19 +3,19 @@
 ##

 # JDBC接続ドライバクラス(DataSourceを直接使用する際の項目)
-nablarch.db.jdbcDriver=org.h2.Driver
+nablarch.db.jdbcDriver=org.postgresql.Driver

 # JDBC接続URL(DataSourceを直接使用する際の項目)
-nablarch.db.url=jdbc:h2:./h2/db/rest_example
+nablarch.db.url=jdbc:postgresql://localhost:5432/rest_example?ApplicationName=rest

 # DB接続ユーザ名(DataSourceを直接使用する際の項目)
-nablarch.db.user=REST_EXAMPLE
+nablarch.db.user=rest_example

 # DB接続パスワード(DataSourceを直接使用する際の項目)
-nablarch.db.password=REST_EXAMPLE
+nablarch.db.password=rest_example

 # DBスキーマ名(DataSourceを直接使用する際の項目)
-nablarch.db.schema=PUBLIC
+nablarch.db.schema=public

 # 最大プールサイズ(DataSourceを直接使用する際の項目)
 nablarch.db.maxPoolSize=5
diff --git a/src/main/resources/rest-component-configuration.xml b/src/main/resources/rest-component-configuration.xml
index 8b65cf6..0c9c066 100644
--- a/src/main/resources/rest-component-configuration.xml
+++ b/src/main/resources/rest-component-configuration.xml
@@ -45,7 +45,7 @@
   </component>

   <!-- ダイアレクト設定 -->
-  <component name="dialect" class="nablarch.core.db.dialect.H2Dialect" />
+  <component name="dialect" class="nablarch.core.db.dialect.PostgreSQLDialect" />

   <!-- ハンドラキュー構成 -->
   <component name="webFrontController" class="nablarch.fw.web.servlet.WebFrontController">
diff --git a/src/test/resources/unit-test.xml b/src/test/resources/unit-test.xml
index 054e05a..1ca371c 100644
--- a/src/test/resources/unit-test.xml
+++ b/src/test/resources/unit-test.xml
@@ -19,7 +19,7 @@
     <property name="schema" value="PUBLIC"/>
   </component>

-  <!-- テスト用HttpServerにJetty6を定義する -->
-  <component name="httpServerFactory" class="nablarch.fw.web.httpserver.HttpServerFactoryJetty6"/>
+  <!-- テスト用HttpServerにJetty9を定義する -->
+  <component name="httpServerFactory" class="nablarch.fw.web.httpserver.HttpServerFactoryJetty9"/>

 </component-configuration>
```