[Apache Hop] ローコードでETL処理を実装してWebサービスにしてみた(同期編)

# 紹介したいこと

**以下のようなETL処理をローコードで実装して、Webサービスとして公開できてしまうのです。**
**OSSでこんなことできてしまうのは、凄くないですか？**
部品が充実していて、やりたい処理実現が見越せていたら、こんな方法もありますよということで紹介させていただきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/7f5af817-833d-e922-8d61-e468a59e8952.png)

データ変換処理の定義例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/69b762df-fe0f-d64e-673d-ea2059913be3.png)
CSV入力 > フィルターで抽出 > JSON形式で出力

# 対象者
- Apache Hop (データ統合プラットフォーム) を使ってみたいかた。データ収集、変換処理をしたいかた。
- ローコードでETL処理を実装してWebサービスを作成したい方。
- 外部から変換処理を呼び出し、変換結果を利用する方法を検討されているかた。


# 前提環境
- Apache Hopの環境を構築している
現時点(2022/04/29時点)で最新であるApache Hop 1.2.0を例として説明します。

https://qiita.com/Tadataka_Takahashi/items/f13161b981a8699f46ff

https://qiita.com/Tadataka_Takahashi/items/58f69ceb466a5c3a295a

- Hopサーバの設定として、HOP_PROJECT_FOLDER, HOP_PROJECT_NAME を定義します。次のページを参照して定義してください。

https://hop.apache.org/manual/latest/hop-server/web-service.html#_hop_server_configuration

- Dockerで環境構築したので、docker-complse.yml(ページ下の設定ファイルの例)を用いてdockerの構成を作成しました。ホストOSにも、hopのファイルを配置して、Dockerからも参照するようにしました。
      
# 手順の流れ
- 変換処理を定義する
- Webサービスとして公開する
- 動作を確認する

## 変換処理(パイプライン)の定義
- Hop GUIを起動してパイプラインを新規作成します。
- CSVファイル(ブック情報一覧)でテーブル情報を入力します。
- Java filterで条件に該当するデータを抽出します。
- JSON ouputで結果を出力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/37f0c3e7-546e-b0e6-ddaf-367d05e1b1b9.png)

CSVの定義については、以下のページを参照ください。

https://qiita.com/Tadataka_Takahashi/items/f5551b0ad6f74a054b9c

Java filterでは、Titleに指定した文字列が含まれるものを抽出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/93798a44-9390-3bd9-c160-1e522bd427a5.png)

上記の条件にでてくる${para1}は、この変換処理(パイプライン)のパラメータとして定義しています。Webサービスでアクセスするときには、引数として指定することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/bd470afc-daec-c95b-9608-c3953e34822c.png)

JSON ouputでは、右から流れてきたデータをoutputValue変数にJSONとして出力します。Nr rows in blockは複数行の結果を1つのグループして出力するため、0を指定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/b62f0fb6-7e88-2147-0d77-dddeaeab320a.png)

Get Fieldsボタンで出力するフィールドを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/53e282f9-21f6-61d4-06b2-70f4f7a5a562.png)

## Webサービスとして公開する

- Hop GUIのMetadataタブを開き、Webサービスを右クリックしてNewで定義を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/416e76ac-c893-fd69-edd9-cb514086431f.png)

- Webという名前でサービスを定義して保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/487685fd-7d9f-bc90-c3ff-cb19c8b931d9.png)

Enables?: 有効にするためチェックします。
Filename on the server: 上記で定義したパイプライン(変換処理)の定義ファイルを定義します。
Output transform: JSON ouput部品を指定します。
Output filed: outputValueのフィールドを指定します。
Content type: application/jsonを指定します。
List status on server: サーバで監視する状態にするので、チェックします。

## 動作を確認する
コマンドプロンプトでcurlコマンドで非同期処理を実行します。
```
curl -u cluster:cluster -i -s "http://localhost:8081/hop/webService/?service=Web&para1=%E8%A8%80%E8%AA%9E" -X GET
```
書式としては、serviceの名前、パラメータのKey,Valueを&でつなげていく感じです。
http://localhost:8181/hop/webService/?service=test&A=valueA&B=valueB

以下のようにJSON出力が返ってくる。
```
{"data":[{"PublishDate":39837,"ISBN":"978-4-87311-394-4","Price":4180,"Title":"プログラミング言語 Ruby","ImageUrl":"https:\/\/www.oreilly.co.jp\/books\/images\/picture_large978-4-87311-394-4.jpeg","URL":"https:\/\/www.oreilly.co.jp\/books\/9784873113944\/"},{"PublishDate":40492,"ISBN":"978-4-87311-470-5","Price":4180,"Title":"入門 自然言語処理","ImageUrl":"https:\/\/www.oreilly.co.jp\/books\/images\/picture_large978-4-87311-470-5.jpeg","URL":"https:\/\/www.oreilly.co.jp\/books\/9784873114705\/"},{"PublishDate":41775,"ISBN":"978-4-87311-683-9","Price":1540,"Title":"word2vecによる自然言語処理","ImageUrl":"https:\/\/www.oreilly.co.jp\/books\/images\/picture_large978-4-87311-683-9.jpeg","URL":"https:\/\/www.oreilly.co.jp\/books\/9784873116839\/"},{"PublishDate":42391,"ISBN":"978-4-87311-752-2","Price":3520,"Title":"Go言語によるWebアプリケーション開発","ImageUrl":"https:\/\/www.oreilly.co.jp\/books\/images\/picture_large978-4-87311-752-2.jpeg","URL":"https:\/\/www.oreilly.co.jp\/books\/9784873117522\/"},{"PublishDate":43267,"ISBN":"978-4-87311-822-2","Price":3740,"Title":"Go言語でつくるインタプリタ","ImageUrl":"https:\/\/www.oreilly.co.jp\/books\/images\/picture_large978-4-87311-822-2.jpeg","URL":"https:\/\/www.oreilly.co.jp\/books\/9784873118222\/"},{"PublishDate":43399,"ISBN":"978-4-87311-846-8","Price":3080,"Title":"Go言語による並行処理","ImageUrl":"https:\/\/www.oreilly.co.jp\/books\/images\/picture_large978-4-87311-846-8.jpeg","URL":"https:\/\/www.oreilly.co.jp\/books\/9784873118468\/"}]}
```

PowerBIでWebサービスにアクセスしてダッシュボードを作成して可視化することをやってみました。
Titleに言語が含まれるブックの一覧をアプリケーションで表示している例です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/c5f4aab6-4d45-8561-9fcc-4f2d18b5a7f3.png)


以下のページにアクセスすると、Webサービスの実行の履歴、状況を確認することができます。
http://localhost:8081/hop/status/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/48cd0f68-2709-6e58-18af-89166b6da929.png)

対象の項目を指定して、ボタンで実行、停止、詳細の参照ができます。

# まとめ
- ローコードでETL処理を実装して、Webサービスとして公開することをためしてみました。このWebサービスの機能は、Apache Hopの特徴の機能の1つとなります。
- 今後に時間があれば非同期処理のWebサービスもあるので、それについても投稿できたらと考えています。

# 感想
- GUIで実行したときの変換処理は、ストレスなく動いている。自分でスクリプト実装していた処理よりも速く動いてる体感である。
- Dockerについては、どこに何のファイル、フォルダがあるのか。ファイルを編集する術を知るのが、大変であった。はじめての場合にはJavaのみでの環境で試してから、感覚をつかむほうがよさそうであった。
- Hop Webの画面のレスポンスは、まだまだこれからで発展途上でありそう。
- 日本語言語、時刻の設定、時間の調整、セキュリティの設定、エラーハンドリング、ログの確認方法など、本格的な運用のことを考えると、まだ調査が必要な項目は多くある。ただし、処理の流れがある程度見えていて、試してみたいなどについては活用できそうである。

# 参考

https://hop.apache.org/manual/latest/hop-server/web-service.html

# 設定ファイルの例
docker-complse.yml
```
version: '3'
services:

  hop1:
    image: aacc73292e53
    container_name: hop    
    ports:
      - 8083:8080
    user: root
    volumes:
       - ./:/files
    environment:
       HOP_LOG_LEVEL: Basic
       HOP_PROJECT_FOLDER: /files/config/projects/default
       HOP_PROJECT_NAME: default
  hopWeb1:
    image: faaa970e7332
    container_name: hopWeb
    ports:
      - 8082:8080
    volumes:
       -  ./:/files
```
# 参考

HopのDockerの使い方、設定項目など:

https://hop.apache.org/tech-manual/latest/docker-container.html#top