Deploy JBoss EAP for OpenShift

## やること

* Red Hat Certified の JBoss EAP のベースイメージを用いた、OpenShift 上でのビルド方法を試す。
* （[Katacoda](https://www.katacoda.com/courses/openshift/middleware/middleware-javaee8)のメモ）

## JBoss EAP ?
* JBoss EAP は、Jakarta EE8 を完全にサポートする主要なJakartaEE プラットフォーム
* JBoss EAP のバージョン6以降は、仮想環境やベアメタルと同様にクラウド環境で動かせるように設計されている

## 天気予報アプリ

### アプリの概要

* Jakarta EE 8の最も一般的な機能を説明するために、「WeatherApp」と呼ばれるWebアプリケーションを作成する。
* このアプリケーションを使用すると、ユーザーは国ごとの最大の都市の天気情報を確認できる。
* ユーザーは、メニューのフラグの1つをクリックして、国を切り替えることができます。

### アプリを動かすステップ

1. プロトタイプをOpenShiftにデプロイします
2. データベースから気象情報を読み取る（最初は内部）
3. ユーザーが国を選択できるようにする
4. アプリケーションを気象情報を含む外部データベースに接続します

### アプリの構造

* フロントエンド
    * SPA (./src/main/webapp/index.html)
    * BootstrapとjQueryを使用する
    * RESTを使用してバックエンドに接続する

* ドメインモデル
    * ./src/main/java/com/redhat/example/weather/Country.java
    * ./src/main/java/com/redhat/example/weather/City.java

* JAX-RSを使ったRESTアプリケーション
    * プロトタイプではすでに、フロントエンドが国のオブジェクトと表示する都市のリストを取得するための、シンプルなRESTベースのサービスを実装している。
    * JAX-RSを有効にするには、`javax.ws.rs.core.Application`を拡張したクラスを用意し、サービスを公開するためのベースURI（パス）を設定する必要がある
    * プロトタイプでは、これを `src/main/java/com/redhat/example/weather/RestApplication.java` で行っている。
    * このクラスでは、ベース URI を `/api` に設定している。
    * これは、この URI を使用したバックエンドへの呼び出しが、JAX-RS サブシステムにルーティングされることを意味する。

* 天気予報のRESTサービス
    * `src/main/java/com/redhat/example/weather/WeatherService.java` は、すでにJAX-RSを使用したシンプルなRESTサービスを実装しており、現在ハードコーディングされている1つの国を含むListを返す。

* ユーザーのステート
    * 利便性のために、このプロトタイプには `src/main/java/com/redhat/example/weather/SelectedCountry.java` も含まれている。
    * このクラスは現時点では使用していませんが、後ほど使用する予定である。
    * このクラスは @SessionScope でアノテーションされており、このクラスの状態がセッション・スコープに保存されるべきであることをアプリケーション・サーバーに伝える。
    * 例えば、フロントエンドからバックエンドへの異なるリクエスト間でも、ステートは維持される。
    * しかし、ユーザーがブラウザを閉じたり、長い間活動しなかったりすると、状態は削除される。
    * セッションを使用することは、ユーザーの一時的な状態を保存するのに便利な方法であり、それらの情報の永続化のためには、一般的にデータベースが使用される。

* ビルド設定
    * プロトタイプでは、pom.xmlにビルド設定も含まれている。
    * ビルド設定は非常にシンプルだが、wildfly-maven-pluginが含まれている。
    * 今回はOpenShiftにデプロイするため、このプラグインは使用しないが、このプロジェクトをローカル開発のベースとして使用したい場合は、このプラグインが使用できる。

## Deploy to OpenShift

アプリを構築するために、適切なJavaランタイムがインストールされてる。以下のコマンドでラインタムが利用可能であることを確認する。

##### コマンド

```bash
$JAVA_HOME/bin/java --version
```

##### レスポンス

```bash
openjdk 11.0.10 2021-01-19
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.10+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.10+9, mixed mode)
```

### 1. Login to OpenShift Container Platform

OpenShift Container Platformへの認証を行うために、ocコマンドを使用し、認証を行うサーバーを指定する。

##### コマンド

```bash
oc login -u developer -p developer
```

### 2. Create project

このシナリオでは、OpenShiftにデプロイする製品を管理するRESTサービスを構築する。

##### コマンド

```bash
oc new-project my-project --display-name="Weather App"
```

### 3. Open the OpenShift Web Console

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325101/7dca95a2-6683-92eb-0602-6dab10814b10.png)

以下のUsername、Passwordで、Web Console で認証を行った後、新たに作成したマイプロジェクトを含む、作業可能なプロジェクトの一覧が表示される初期画面が表示されることを確認する。

* Username :`developer`
* Password :`developer`


### 4. Deploy JBoss EAP image

アプリケーションをデプロイするには、まずコンテナを作成する必要がある。
JBoss EAP のベースイメージには、ランタイムに必要なすべてのバイナリをパッケージ化したS2Iイメージが付属している。
S2IはSource-To-Imageの略で、開発者が成果物（WAR、JARなど）やソースコードを直接提供すると、OpenShiftがコンテナイメージを構築してくれる便利な方法である。
そのため、ローカルのコンテナ構築システムは不要で、開発者はベースイメージのパッチ適用やメンテナンスを気にする必要はない。

![image.png](https://cloud.redhat.com/hubfs/Imported_Blog_Media/S2IDeveloperWorkFlow1.png)
[Source-to-Image (S2I) Deep Dive with Ben Parees - OpenShift Commons Briefing #43](https://cloud.redhat.com/blog/source-image-s2i-deep-dive-ben-parees-openshift-commons-briefing-43)

ここでは、以下のコマンドを使用して、OpenShiftに**build config** を作成します。

##### コマンド

```bash
oc new-build jboss-eap73-openjdk11-openshift:7.3 --binary=true --name=weather-app
```

このコマンドは、weather-appという名前のJBoss EAP 7.3を含むベースイメージを使用するようにopenshiftに指示し、最後に**Binary Deployment** と呼ばれるものを使用するように指示する。
**Binary Deployment** とは、Javaの成果物をローカルで、mavenを使用して構築し、S2Iプロセスがその成果物をJBoss EAPにデプロイするコンテナを構築することを意味する。

次に、デプロイするアプリケーションのプロトタイプを作成する。
mavenコマンドを実行して、アプリケーションをビルドする。

##### コマンド

```bash
cd ~/projects/rhoar-getting-started/javaee/weather-app
mvn clean package
```

これで、作成した成果物（WARファイル）を、先ほど作成したビルド「weather-app」プロセスにアップロードする準備が完了した。

##### コマンド

```bash
oc start-build weather-app --from-file=target/ROOT.war --follow
```

このコマンドを実行すると、先ほど作成した**build config** にアーティファクト(ROOT.war)がアップロードされ、コンテナの構築が開始されます。初回実行時には、OpenShift がJBoss EAP のベースイメージをダウンロードする必要があるため、しばらく時間がかかることがある。（次回からはもっと早くなる。）

ビルドが終了すると、コンテナを起動する準備が整う。

##### コマンド

```bash
oc new-app weather-app -l app.openshift.io/runtime=jboss
```

`new-app` コマンドを実行すると、先ほど構築したコンテナをベースにした実行中のインスタンスが作成され、OpenShiftのWeb ConsoleのTopology Viewでアプリケーションが正しく表示される。

### 5. Expose service route

アプリケーションがコンテナ内で実行されるようになったので、アプリケーションを OpenShift の内部ネットワーク外からアクセスできるようにする必要がある。
そのためには、OpenShift IngressからのトラフィックをServiceに転送するRouteを作成する必要がある。

##### コマンド

```bash
oc expose svc weather-app
```

このコマンドを実行すると、Topology View上に新しいルートリンクのアイコンが表示される。これをクリックすると、アプリにアクセスできる。

## メモ

* `start-build` で出来上がったイメージにstandalone.xml とかの ConfigMap を注入するときは[ここ](https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.3/html-single/getting_started_with_jboss_eap_for_openshift_container_platform/index#creating-a-configmap-from-standalone-xml-file_default)。`standalone-openshift.xml`も書き換えられそう。
* 受け付けられる環境変数は[ここ](https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.3/html-single/getting_started_with_jboss_eap_for_openshift_container_platform/index#reference_configuration_environment_variables)。
*