Open LibertyのFeatureをプライベートリポジトリからダウンロードする

Javaアプリケーションサーバ [Open Liberty](https://openliberty.io) は、Jakarta EEおよびMicroProfileの機能を使用する際にFeatureと呼ばれるモジュールを使用します。使いたい機能に対応したFeatureのみインストールすることで、比較的小さなアプリケーションサイズになり、起動時間も短くなるメリットがあります。

FeatureはMaven Central Repositoryに保管されたパッケージです。
そのため、企業NWで接続先を制限しているとFeatureをインストールができない状態になる場合があります。

この記事ではMaven Central Repositoryではなく、プライベートリポジトリからFeatureをインストールする方法を記載します。


## 環境情報

* JDK ... OpenJDK 17 IBM Semeru Runtime Open Edition
* Open Liberty ... 22.0.0.12


## いきなり結論: 環境変数をセットする

FeatureはOpen Liberty付属のコマンドライン・ユーティリティ `featureUtility` を使用してインストールします。

いきなり結論ですが、featureUtilityは環境変数 (またはプロパティファイル `featureUtility.properties`) でプライベートリポジトリの接続先を指定可能です。環境変数を利用する場合は以下のパラメータを指定します。

|環境変数名|説明|
|:--|:--|
|`FEATURE_REPO_URL`|プライベートリポジトリのURL|
|`FEATURE_REPO_USER`|プライベートリポジトリのユーザー|
|`FEATURE_REPO_PASSWORD`|プライベートリポジトリのパスワード|


## 実践

Open LibertyのREST APIアプリケーションのサンプルをベースにプライベートリポジトリからFeatureをインストールしたアプリケーションを作成します。

サンプルアプリケーションは[公式ドキュメントのガイド](https://openliberty.io/guides/rest-intro.html)を、JDK 17をターゲットにビルドできるように改変したものを使います。
また、Open Libertyのインストールを簡易にするため、[IBM Container Registryで提供される公式コンテナイメージ](https://github.com/OpenLiberty/ci.docker/blob/main/docs/icr-images.md)を使用します。

### 事前準備

事前にプライベートリポジトリを立てて、Featureをこのリポジトリに格納します。

※ Featureの格納方法は当記事では解説しません。

### Featureの指定

Featureを `server.xml` に指定します。
この記事ではサンプルアプリケーションで指定されている以下2つを使用します。

* Jakarta RESTful Web Services 3.0
* Jakarta JSON Binding 2.0

```xml
<!-- server.xml -->
<server description="Intro REST Guide Liberty server">

  <featureManager>
    <feature>restfulWS-3.0</feature>
    <feature>jsonb-2.0</feature>
  </featureManager>

  <!-- 他の設定は省略 -->
</server>
```

### Featureをインストールする

簡易のためOpen Libertyをコンテナで用意して、アプリケーションをビルドしてみます。

コンテナイメージで用意されたOpen LibertyでFeatureをインストールおよびビルドする際には、`featureUtility`のラッパースクリプト`features.sh`を使用します。
以下にラッパースクリプトを使用するサンプルのDockerfileを示します。

```dockerfile
FROM icr.io/appcafe/open-liberty:kernel-slim-java17-openj9-ubi

# ここでFeatureを指定したserver.xmlをコピー
COPY --chown=1001:0 /src/main/liberty/config /config

# server.xmlの定義に従ってFeatureをインストール
RUN features.sh

COPY --chown=1001:0 target/*.war /config/apps

RUN configure.sh
```

コンテナランタイムのビルド環境変数にプライベートリポジトリの接続情報を渡し、Featureをプライベートリポジトリからインストールするコンテナイメージをビルドします。以下のサンプルでは `10.22.33.45:8081` に立てたプライベートリポジトリを指定します。

```bash
$ # WARファイルをビルド
$ mvn clean package -DskipTests -B -ntp

$ ls target/*.war
target/guide-rest-intro.war

$ # Dockerfileを配置
$ ls Dockerfile
Dockerfile

$ # Featureのリポジトリにプライベートリポジトリを指定してコンテナイメージをビルド
$ podman build . -t liberty-rest-sample:v1 \
    --env=FEATURE_REPO_URL=http://10.22.33.45:8081/repository/maven-public \
    --env=FEATURE_REPO_USER=admin \
    --env=FEATURE_REPO_PASSWORD=samplepassword
```

Featureインストール済みのコンテナイメージからアプリケーションを起動すると、指定したFeatureおよび依存するFeatureを使用して起動することがわかります。

```bash
$ podman run --rm -p 9080:9080 --name liberty-rest-sample liberty-rest-sample:v1 

Launching defaultServer (...中略...)
[AUDIT   ] CWWKF0012I: The server installed the following features: [cdi-3.0, concurrent-2.0, jndi-1.0, jsonb-2.0, jsonp-2.0, restfulWS-3.0, restfulWSClient-3.0, servlet-5.0].
[AUDIT   ] CWWKF0011I: The defaultServer server is ready to run a smarter planet. The defaultServer server started in 9.027 seconds.
```

## 参考情報

* [Open Liberty - featureUtility commands](https://openliberty.io/docs/latest/reference/command/featureUtility-commands.html)