Talend入門(13) ～設定ファイル読み込み～

##全体の目的
Talendの超簡単なサンプルジョブを作成して，ETLジョブ開発に必要なスキルを習得することが目的です。

##対象者
ETL / EAI技術者

##環境
|使用環境|バージョン|
|:----:|:------------------|
|OS|Windows10|
|Talend|7.2.1|

##サンプル一覧
以下の順番で習得していきます

|#|内容|
|:----:|:------------------|
|1|[はじめてのTalend](https://qiita.com/airkoda/items/a837d3c5d851d98d2612)|
|2|[ファイルI/O](https://qiita.com/airkoda/items/1cd12c05c6136add7178)|
|3|[データベースI/O](https://qiita.com/airkoda/items/bc807c920c3adebad837)|
|4|[tMap](https://qiita.com/airkoda/items/fa4a9c022b5d688698e0)|
|5|[イテレータ](https://qiita.com/airkoda/items/404d2d65eff535b2126c)|
|6|[メタデータ](https://qiita.com/airkoda/items/4b42cf2a86f34abb6c87)|
|7|[Context変数](https://qiita.com/airkoda/items/42d294fca40b81aa20fb)|
|8|[Global Map](https://qiita.com/airkoda/items/1aba0d36905c755deeae)|
|9|[tHashInput/tHashOutput](https://qiita.com/airkoda/items/d9347865190f0f3ab180)|
|10|[エラーハンドリング](https://qiita.com/airkoda/items/85e7c49a9bf6a21db6d5)|
|11|ロギング|
|12|子ジョブ（ジョブのネスト）|
|**13**|**[設定ファイル読み込み(今回)](https://qiita.com/airaotaku/items/92f114795108f25e6d0f)**|
|14|[tJava](https://qiita.com/airkoda/items/4d81d76c36b6fcbd4d89)|

[サンプルコード（Talendプロジェクトデータ）](https://github.com/airaaoki/air_sample/tree/master/PRJ_QIITA)

##今回の目的
今回はよく使う変数を記録したファイルを保持しておき、TalendJobから容易に参照することを目的とします。



##設定ファイルの作成
テキストエディタで今回読み込むconfig用のファイルを作成しましょう。

検証用/商用を区別した設定ファイルをTalend内の設定を変えることで別に読み込めるようにしたいので、

|使用用途|フォルダ名|ファイル名|
|:----:|:---|:-----------------|
| 検証用 |config_develop| develop.properties |
| 商用 |config_prioduct| product.properties |

と仮定してファイルを二つ用意します。
拡張子に特にこだわりはありませんが、設定ファイルであることを識別するためにpropertiesとしています。

コメントを書きたいので、変数定義の箇所とそれ以外を識別できるようにしておくといいですね。
今回は「#」をコメント行の識別に使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/4c958fb3-01f8-86b2-870d-9de9047baec6.png)
1行目、3行目がコメント、4行目が読み込む変数となります。

あとでTalend側でも設定を合わせますが、
改行コードは「\n」(LF)、エンコードはUTF-8にします。

##設定ファイルの配置
続いて、作成したファイルを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/9c9d18f0-f85e-e4d1-a0f2-05a3dc4066a7.png)
検証用、商用でファイルを分けているので、別のフォルダに配置します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/6a6b654a-f426-6e48-81fc-e84c0bf9a174.png)

置きました。


お次はジョブの作成に入っていきます。

##新規ジョブの作成
ジョブを新規作成してください。

リポジトリの「ジョブ」を右クリックし、「ジョブの作成」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/14fc3c95-7e25-18bb-99a6-c6ff919d67d5.png)

今回作成するジョブの名前と簡単な説明を付記してあげます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/54bca629-788e-d468-79d5-2746b70a71e7.png)

##contextに変数を書き込む
ジョブ側に各種変数をあらかじめ保持しておく「Contexts」タブなるものがあります。
デフォルトでは「Contexts」タブにはなにも入っていません。

Talendでは、「Contexts」タブにジョブ全体で保持することのできる変数を定義できます。
ここに設定した変数はcontext.**[Contextsタブに設定したキー]**で取得することができます。

Contextsタブでは、左下の「＋」ボタンで行の追加、右上の「＋」ボタンで列の追加が可能です。
行が変数、列が値に当たります。
画像左下の「＋」ボタンを押下し変数を追加します。
今回は変数名は「config_filepath」とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/6440d4ac-8193-21b4-9718-69c2e274f2fa.png)

続いて画像右上の「＋」ボタンを押下し、値を追加します。
「Value」欄に入るのが文字通り変数の値になります。
値を追加することで使用する環境に応じて使い分けが可能です。今回は列名を「Products」とします。
Typeはここに入れるデータ型をプルダウンで選択する箇所になりますが、今回はString型なのでそのままです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/b83af094-6627-8591-e320-7cae7630d580.png)
今のところこんな感じです。

続いて、変数に入れる値を記載します。


|列名|値|
|:----------|:--------------------------------------------------------------------------------------------------|
|Default   |"C:/Talend/TOS_DI-20190620_1446-V7.2.1/workspace/PRJ_QIITA/config_develop/develop.properies"|
|Products  |"C:/Talend/TOS_DI-20190620_1446-V7.2.1/workspace/PRJ_QIITA/config_prioduct/product.properties"|



をそれぞれ記載します。
ここは相対パスでも絶対パスでも大丈夫です。
注意点としては、通常Windowsでのパスは"\"を区切り文字として使用しますが、Talendでは"**/**"を使用しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/9c156862-70d3-ba8d-a5cc-e3906866ad66.png)

入れました。

また、設定ファイルに記載した変数「OUTPUT_WORD」用の箱を用意します。Valueは空欄でいいです。
ここの空欄に入る値を設定ファイルから取得し、ジョブの中で取得する、というのが今回の趣旨に当たります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/31d8fd36-ab83-7eb2-f19e-fe57b9b82e30.png)
ここのValueに設定ファイルで記載した```HELLO,WORLD@検証用```をジョブ内で代入させます。



Talendはアプリの生成時に使用するContextsのカラムを指定できるので、検証用/商用で設定ファイルを使い分けることができます。

今回使用するコンポーネントをは下記の通りです。

|コンポーネント名|役割|
|:-------------|:----------------|
|tFileInputFullRow|ファイルを全行読み込む|
|tFileteraRow|コメント行を削除する|
|tMap|変数のキーと値を分ける|
|tContextLoad|キーと値をコンテキストに設定する|
|tLogRow|結果の確認(確認後削除します)|

##tFileInputFullRowの配置
デザイナー部分で「tFileInputFullRow」と打つ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/4710bf11-0ab8-9231-946c-a71f9f358c6c.png)

いろいろサジェスチョンが出てきますが、今回は「tFileInputFullRow」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/40dd7d85-2fb8-ccc5-e89e-7ccb3f4cadf6.png)
デフォルトで入っているファイル名は消してしまって問題ありません。
「tFileInputFullRow」コンポーネントを選択し、画面下のコンポーネントタブの「表示」から「configの読み込み」という名称を付加しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/09175a98-39dd-e3f6-487f-e3799962d107.png)

そのままでは使用できないので、コンポーネントタブにて下記修正を加えます。
・「基本設定」の「ファイル名」に「**context.config_filepath**」と入力する
　　　--これにより先ほど「Contexts」タブに設定した「config_fileath」の値を参照することができます。
・「基本設定」の「空の行をスキップ」にチェックを入れる
　　　--これによりファイルを読み込んだ際に空行以外を入力として使用します。
・「詳細設定」のエンコードを先ほど作成した設定ファイルと揃える
　　　--今回はUTF-8で作成したので、UTF-8を使用しています。
・「表示」から「configの読み込み」と入力し、コンポーネントの表示名を変える
　　　--可読性の向上のためです。
　　　　(Talendは、それぞれのコンポーネント内部で何を行っているかがわかりづらいため、こまめに表示名を変えましょう。)

####tFileInputFullRowを経る前の設定ファイルのイメージ
```develop.properies
#【検証用】Talendで読み込む設定ファイルです。

#設定を読み込めたかの確認用
OUTPUT_WORD=HELLO,WORLD@検証用
```

#####tFileInputFullRowを経た設定ファイルのイメージ
```develop.properies
#【検証用】Talendで読み込む設定ファイルです。
#設定を読み込めたかの確認用
OUTPUT_WORD=HELLO,WORLD@検証用
```
このように、空行がスキップされています。

お次は、設定ファイル内のコメント行(文頭に#で記載した行)の削除を行います。




##tFilterRowの配置
Designer上で「tFileteraRow」と入力し、コンポーネントを配置する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/1135e9b2-ab6d-b422-57e2-f4082d57f118.png)


このコンポーネントは、コンポーネント間を接続する際にフィルターかリジェクトを選択できるのが特徴。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/6d09ee4d-82db-bb03-2b93-3c8cc809edab.png)


画面下部の「コンポーネント」タブにて下記編集を行う。
・「基本設定」から「上級モードの使用」にチェックを入れる
・表示された「詳細」欄に以下を入力
```!(input_row.line.matches("^#.*"))
```　--文頭に#のある行以外を抽出している
・「表示」タブにて、「コメント行削除」を入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/6e3797ea-6305-c647-cf3a-55b68141f7a6.png)

#####tFileteraRowを経た設定ファイルのイメージ
```develop.properies
OUTPUT_WORD=HELLO,WORLD@検証用
```
コメント行以外が抽出されました。

##「tMap」の配置
Designer上で「tMap」と入力し、tMapコンポーネントを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/40849271-2253-d142-2aaa-cfd35059d045.png)

のみが入ってきているはずなので、
これを左辺と右辺とでkeyとvalueに分けてしまいます。

「tMap」はデータマッピングを行うコンポーネントです。
コンポーネントをダブルクリックすると下図のようなマッパー画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/bb92a45c-568e-ea11-6e5a-bc1596ab09e6.png)

ここではjavaの式を使用して文字列の操作やフィルタリングが可能です。

画面左の「line」は「row2」に入っている行です。
これをkey,valueの形にします。
具体的には下記の編集を加えます。
・「コメント行削除」を右クリックし、「ロウ」＞「フィルター」を選択し、tMapに接続
・右ペインの画面上部「＋」ボタンをクリックし、「out1」を作成。
　--「out1」はtMapのアウトプットになる
・tMapをダブルクリックし、マッパー画面を表示。
・左ペインの「row2」の「line」を、右ペインの「out1」の下にドラッグアンドドロップ
　--これを2回行う。
・右ペインに式を入力し、「line」の左辺と右辺をに分割する
　--**substring(indexOf())**を駆使し、lineの中で一行で記述されている変数=値を"="の左辺と右辺に分割する。
・画面下部の「スキーマエディター」タブより、「out1」の「line」「line_1」をそれぞれ「key」「value」に変更する
tMap途中イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/bce497b1-b1a0-143a-2fd2-8e78e2db4076.png)

tMap完成図イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/d47901af-d761-8bdf-f1ac-4c3dd2a8de23.png)

##tContextLoadコンポーネントを配置
「tContextLoad」を配置します。
・「表示」から、表示名を「コンテキスト設定」に変更します。

このコンポーネントは、「key」「value」の形で渡された情報をcontextとして保持するコンポーネントです。
ここまで来た時点で設定ファイルから渡された情報は、ハッシュの形をとっているため、特にこのコンポーネントで行うことはありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/2521967b-df51-8105-1b7f-f670b6bd5017.png)

##試しに動かしてみよう

実行してみます。
ただし、このジョブはコンテキストを読み込み、内部に保持するだけのジョブなので、
実行結果が外からわかるようにログの設定をしてあげる必要があります。

こういったときに役に立つのが、「tLogRow」コンポーネントです。
「tLogRow」を配置し、テーブルの形で出力してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/63deee29-7845-b7fa-6b48-77cd707099a5.png)

実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/da7cf7be-30f0-d2c6-2d94-57fc0cc0b0fd.png)


Designer部分には行ごとの実測処理時間や処理行数が表示されます。
実行タブにはログが表示されます。
ログを見ると、
keyにOUTPUT_WORD
valueにHELLO,WORLD@検証用
が表示されていますので、成功です。

実行結果を確認したら、「tLogRow」コンポーネントを削除することを忘れないようにしましょう。
**消し忘れると半永久的にいらないログが出力されるようになります。**


##念のため、商用に作成したものも読み込んでみます。

「contexts」タブの「デフォルトのコンテキスト環境」のプルダウンを「Products」に変更し、実行します。
**実際に開発を行っているプロジェクトではこのやり方は推奨しません。行う場合は自己責任でお願いします。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/e4500a38-9db1-1959-8ac0-a20b13668274.png)


実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376167/d787a327-8f23-0621-e2a5-06ab4b61ffc6.png)


出力される値が変わっていることが確認できました。
このように、読み込むテキストを変更することで、環境に応じてContextsを変更することが可能です。


##まとめ
テキスト上に記載した変数と値のセットを読み込み、
フィルタリングやjavaの式を通じてkey,valueの形に成形することで、tContextLoadで取り込みを行い、
Contextsタブ上に定義した変数として抽出することが可能です。

また、Contextsに値のセットを複数持つことで、環境に応じて使い分けが可能となります。


##次回以降
次回はtJavaをやっていきます。

##もっと簡単に実現している記事
[【Talend】2つのコンポーネントだけで簡単に設定ファイルを読み込む](https://qiita.com/airyama/items/83c2bf9b2d51a79c3714#tcontextload)