JS7® JobScheduler 初期設定、サンプルWorkFlowの登録

# 概要

JS7 JobSchedulerの稼働後の初期設定、サンプルデータを登録する方法、および各サンプルの概要を説明します。
サンプルWorkFlowは、JobScheduler を初めて使う場合の学習用途や、実際にWorkFlowを設定する際の参考データになるかと思います。

# 前提条件

## JS7 jobscheduler の準備
下記ページに従い、docker-compose で joc, controller, agent 稼働環境を用意します。
[JS7® JobScheduler docker-compose で起動](https://qiita.com/natsumadenikimero/items/ffb8f05cbc8e75d435ce)

もしくは通常セットアップした環境があれば、そちらでも利用できます。
※本例はLinux環境前提ですが、WindowsのAgentでも読み替えれば使えると思います。

## Agent Aliasの調整
agent の Alias Names に `primaryAgent` と登録してください。
![add_agent-alias.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/d27497da-629f-9c65-17ab-86807972dd60.png)
※サンプルデータにて、Job実行Agentとしてこの名前が登録されているため。
※Agent Name の変更は、既存環境に影響がでるため、基本的にAliasでの対応を推奨します。



# 初期設定
## Settings

右上のメニューからSettingsを開きます。
![menu-settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/de48835b-9841-754d-0419-00e79adf40a4.png)

dailyplan および cleanup の time zone 設定を行います。
※Saveボタンはありません。変更すれば反映されます。
![menu-settings_timezone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/36081dc1-7c22-b45d-05ad-6766c7315893.png)



## Profile 設定
次に、ログインユーザーごとのProfile設定を開きます。
![menu-profile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/d81ebfcc-b03a-86c9-5cf2-fed228c23122.png)

こちらは好みによりますが、Time Zone および Date Time Format を指定します。
Languageで日本語表示も選べます。
（個人的には英語表記のほうがドキュメントで調べる際に楽なので、このままにします）
![menu-profile_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/17883c5b-2276-dea1-9afc-8cdddf62300c.png)


# サンプルの登録
## サンプルデータのダウンロード
下記メニューより、`default.zip`  `sample.tar.gz`　の2ファイルをダウンロードします。
![inventory_download_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/1c5eaa1b-96ff-a82d-805c-8b89122e2309.png)



## リソース変数の登録
`default.zip`を取り込みます。
これにより、基本的な環境変数の定義を取り込むことができます。
※本リソース変数は、本番／検証環境問わず登録したほうが良いです。



CONFIGURATION － Inventory を開きます。
こちらはWorkFlow、Scheduleなどの定義を行うメニューです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/022777b1-e99a-8f0f-58fd-6d494707bfe6.png)

Import　を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/594d8aa4-ef38-fd3d-9cea-7a4889745c53.png)

`default.zip`を選択し、Import
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/5682fb3f-f7d6-e61e-bf97-8a097ff450c3.png)

これにより、Defaultsフォルダ以下の設定が取り込まれたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/ac1d9df9-a6b4-fe70-5075-466255d25492.png)


## リソース変数の修正
取り込んだDefaultsフォルダを展開し、JobResources の Default（という名前のリソース変数）を編集します。
※Arguments で指定されている値を修正します。Environment Variables は編集しないでください。
ここで指定した値は、WorkFlow中にて環境変数として利用することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/e01608a4-b5d4-5eca-733f-e6139a0b4731.png)

| Name | Value |
|-|-|
| js7JocUrl | JOCへのアクセスに使うURLを指定<br>(例 http://192.168.11.77:4446)|
|js7ScheduledDate|`scheduledOrEmpty(format='yyyy-MM-dd HH:mm:ssZ', timezone='Asia/Tokyo')`|
|js7ScheduledYear|`scheduledOrEmpty(format='yyyy', timezone='Asia/Tokyo')`|
|js7ScheduledMonth|`scheduledOrEmpty(format='MM', timezone='Asia/Tokyo')`|
|以下省略| timezone指定が　`UTC` となっている箇所は `Asia/Tokyo'に修正してください |

※ここで指定した値は、WorkFlow中にて環境変数として利用することができます。
※TimeZoneを修正しないと、該当変数を利用する際に、日付時刻がUTCで返ります。

補足 CentOS7, AmazonLinux2 の環境で試したところ、下記修正が必要でした。
[JS7 - Troubleshooting - Job reports: No such environment variable: COMPUTERNAME](https://kb.sos-berlin.com/display/PKB/JS7+-+Troubleshooting+-+Job+reports%3A+No+such+environment+variable%3A+COMPUTERNAME)

| Name | Value |
|-|-|
|js7AgentHostname|`env('HOSTNAME', env('COMPUTERNAME', ""))`|




修正が終わったらDeployをします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/29fef22e-9203-6f94-87be-19eab6cdd680.png)



これにより、本設定がcontroller, agent に同期されます。

同様に、eMailDefaultも編集、Deployを行ってください。
※本WorkFlowサンプルでは使わないので省略（編集せずDeployでも可）




## WorkFlowサンプル登録
リソース変数と同様の手順で、`sample.tar.gz`をインポートします。
※File Format で TAR_GZ を選んでから選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/481051bf-e4ae-3c8b-94f2-f0aab6151be1.png)

これで、Examples.Unix フォルダ以下の構成が読み込まれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/1f27e96d-f057-091e-7c12-28058e49f36f.png)

登録されたサンプルWorkFlowを一括でDeployします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/0d26dedd-36ff-a623-b7db-c3d43cabe005.png)

Handle recursively のチェックを付けることで、フォルダ以下をまるごと指定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/49c49e3d-467d-06d8-0b2a-014db2e4dc14.png)

各WorkFlowが Deployed となっていることを確認してください。
※Controller,agentへのデプロイが正常にできていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/126fe78a-d282-e41d-dffc-938bbbdc4bd5.png)


同様に、release を行ってください。
これでスケジュール情報が更新されます。
※schedull, calendar などの情報は JOC上のDailyPlan サービス管理であるため、AgentへのDeployはされません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/13bf4759-c7ec-2600-5810-25c11b5e7efc.png)
階層下のSchedule、Working Day Calendar をすべて選択しSubmit
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529537/d7d14068-4206-dfd6-baee-bcc51b06ce3c.png)




以上でサンプルデータの登録作業はおわりです。





# サンプルWorkFlowのざっくりとした説明
各サンプルが何をやっているのか、動作確認の際に注視すべきポイントのメモです。


| workflow Path                                          | 内容 |
| ------------------------------------------------------ | ---- |
| 01_HelloWorld/<br>jduHelloWorld                            | シェルJobおよびリソース変数を利用した基本処理<br>JobResourcese に `/Defaults/Default`を指定することで、ここで定義したリソース変数 `$JS7_WORKFLOW_NAME`,  `$JS7_JOB_NAME` を参照できる|
| 01_HelloWorld/<br>jduHelloRunningLog                       | 秒単位で100までカウント。jobで定義した標準出力がログに随時表示されていくことを確認 |
| 02_ParallelExecution/<br>jduFork                           | Fork（並列処理）サンプル。<br>job1実行後、job2_1x, job2_2x を並列実行。各処理がすべて終了したのを待ち、job3を実行 |
| 02_ParallelExecution/<br>jduForkNested                     | Forkサンプルその２。<br>Fork処理をネストすることが可能|
| 02_ParallelExecution/<br>jduForkList                       | ForkListサンプル<br> Order変数として、countryCodeに BR,FR,UK と3つの値を指定すると、1度のOrder中で、ForkList中のjob1,job2 は、変数毎に個別に並列処理を行う。  |
| 02_ParallelExecution/<br>jduForkListMulti                  | ForkListサンプルその２。<br> Order変数として複数の変数値を指定することができる。|
| 03_VariablesPassing/<br>jduVariablesAdHoc                  | Job中にて`$JS7_RETURN_VALUES` に変数値を追記することで、後続Jobに変数値を渡すことができる。<br>※後続Jobから参照するには、Job環境変数を定義する必要あり。|
| 03_VariablesPassing/<br>jduVariablesDeclared               |WorkFlow変数の定義、参照。Job中の処理で値を変更したい場合は 新たに `new_booking_code`, `new_flight_destination` の値でJob環境変数を定義|
| 03_VariablesPassing/<br>jduVariablesFork                   |Fork処理中は、同一変数名でも分岐している3パターンそれぞれ独立して変数`$new_flight_destination`を上書きできる。Fork終了後は、分岐前のjob1にて渡された変数値が参照される。|
| 03_VariablesPassing/<br>jduVariablesNodes                  | Node引数を利用。※特定Node（Job？）のみで利用可能な変数定義 <br>別途Job環境変数で指定が必要 |
| 04_ErrorHandling/<br>jduFinish                             | デフォルトで、WorkFlow変数にて`return_value_job1 = 0`が指定されている。<br> `$return_value_job1 = 0`のままの場合、job2はスキップし、job3を実行。正常終了となる。<br>Order変数`return_value_job1 = 1`を指定（WorkFlow変数を上書き）して実行すると、条件一致でjob2が実行され、そこまででFinishとなる。    |
| 04_ErrorHandling/<br>jduFail                               | デフォルトで、WorkFlow変数にて`return_value_job1 = 1`が指定されている。<br> `$return_value_job1 > 0`の場合job2実行、Return Code 1 でFailとなる。<br>Order変数`return_value_job1 = 0`を指定（WorkFlow変数を上書き）して実行すると、job3が実行され、正常終了となる。    |
| 04_ErrorHandling/<br>jduReTry                              | job2_bの結果(ランダム値が偶数か？)がエラーの場合10回までリトライ。リトライ時の待ち時間は毎回1秒ずつ増える。<br>※job2_bの割り算を加工してエラーを出やすくすると分かりやすい |
| 04_ErrorHandling/<br>jduWarnIfLongerThan                   | job1の実行時間が`Warn on longer execution period`で指定された3秒以上の場合、通知が飛ぶ <br>※Monitorサービスで通知されるため、別途Notification設定が必要です。|
| 04_ErrorHandling/<br>jduWarnIfShorterThan                  | job1の実行に`Warn on shorter execution period`で指定された10秒以下の場合、通知が飛ぶ |
| 05_ScheduledExecution/<br>jduScheduledWorkflowDaily        | `jduAllDays`カレンダーに従い、毎日実行<br> WorkFlowの画面から scheduled のorder が登録されていることを確認。DailyPlanの画面でも登録を確認。<br>もし登録されていない場合は DailyPlanサービスの再起動でOK |
| 05_ScheduledExecution/<br>jduScheduledWorkflowBusinessDays | `jduBussinessDays`カレンダーに従い月-金に実行 |
| 05_ScheduledExecution/<br>jduScheduledWorkflowCyclic       | 21-22時の間で5分毎に循環実行。 
| 05_ScheduledExecution/<br>jduScheduledWorkflowForkList     | スケジュールからForkList用の`countryCode`値リストを渡して実行 |
| 06_MutualExclusion/<br>jduExclusiveLockSerial              | Exclusive Resource Locks サンプル<br>シンプルなロック。ロック指定箇所は同時に1Taskしか実行できない。<br>3回ほど連続でorderすることで、Lockの動作が確認できる。<br><br>job2_1x側は、前orderのjob2_1b終了後、次orderのjob2_1aが流れる。<br><br>job2_2x側は、前orderのjob2_2c終了後、次orderのjob2_2aが流れる。 |
| 06_MutualExclusion/<br>jduSharedLockSerial                 | shared lockサンプル<br>jduLockBig capacity = 12, duLockSmall capacity = 2 <br>3回ほど連続でorderすることで、Lockの動作が確認できる。<br><br>job2_1x 側は`capacity = 2` に対して`Weight = 2` のため、同時に1Taskしか処理できない。<br>前Orderのjob2_1b終了後、次orderのjob2_1aが流れる（shared lockによる制限）<br><br>job2_2x 側は`capacity = 12` に対して`Weight = 5` のため、同時に2Task処理できる。ただしJobの`Parallelism = 1` であるため、Job単位は同時実行１まで。<br>1回目orderのjob2_2a終了後、2回目orderのjob2_2aが流れる。（Parallelismによる制限）<br>1回目orderのjob2_2c終了後、3回目orderのjob2_2aが流れる。（shared lockによる制限）  |
| 06_MutualExclusion/<br>jduSharedLockParallel               | shared lockサンプル<br>jduLockBig capacity = 12, duLockSmall capacity = 2 <br>3回ほど連続でorderすることで、Lockの動作が確認できる。<br><br>job2_1x 側は`capacity = 2` に対して`Weight = 1` のため、同時に2Task処理できる。ただしJobの`Parallelism = 1` であるため、Job単位は同時実行１まで。<br>前Orderのjob2_1a終了後、次orderのjob2_1aが流れる（Parallelismによる制限）<br>1回目orderのjob2_1b終了後、3回目orderのjob2_1aが流れる。（shared lockによる制限）<br><br>job2_2x 側は`capacity = 12` に対して`Weight = 5` のため、同時に2Task処理できる。<br>1回目orderのjob2_2a終了後、2回目orderのjob2_2aが流れる。（Parallelismによる制限）<br>1回目orderのjob2_2c終了後、3回目orderのjob2_2aが流れる。（shared lockによる制限）|
| 07_ConditionalExecution/<br>jduConditionalVariables        | 条件分岐サンプル<br>WorkFlow変数 `run_job1 = false` `run_job2 = false` 指定あり <br><br>そのままorder登録すると、条件に従い、job2が実行される。<br>Order変数にて`run_job1 = true` を指定することで、job1が実行される。|
| 07_ConditionalExecution/<br>jduConditionalReturnCode       | 前Jobのリターンコードによる条件分岐<br>WorkFlow変数にて`return_code_job1 = 0`, `return_code_job2 = 0`, `return_code_job3 = 0` の指定あり<br>job1,job2,job3は各変数値をリターンコードとして返す。また、リターンコード 0,1,2,3,4 はSuccessとなるように設定あり<br><br>そのままorder登録すると、条件に従い、job1,job2,job4,job5が実行される。<br> Order変数にて `return_code_job1 = 1`を指定すると、job1,job3,job4,job5 が実行される。<br> Order変数にて `return_code_job2 = 1`を指定すると、job1,job2,job5 が実行される <br> Order変数にて `return_code_job1 = 4`, `return_code_job3 = 4`を指定すると、job1,job3,job5 が実行される<br> Order変数にて `return_code_job2 = 5`を指定すると、job2で failedとなる  |
| 07_ConditionalExecution/<br>jduConditionalResult           | `JS7_RETURN_VALUES`環境変数を使っての条件分岐<br>WorkFlow変数にてreturn_code_job1 = 0, return_code_job2 = 0, return_code_job3 = 0 の指定あり<br>job2,job3は各変数値をreturn_value_jobの値としてJS7_RETURN_VALUES環境変数に追記する。また、リターンコード 0,1,2,3,4 はSuccessとなるように設定あり<br>※job1,job2,job3とも変数値を固定値で書き換えてしまうため、うまく動作しないように見える。該当箇所をコメントアウトする必要あり。<br><br>（job1,job2,job3の修正を行った場合の結果）<br>そのままorder登録すると、条件に従い、job1,job2,job5が実行される。<br>Order変数にて `return_code_job1 = 1`を指定すると、job1,job3,job5 が実行される。<br>Order変数にて `return_code_job2 = 1`を指定すると、job1,job2,job4,job5 が実行される。<br> Order変数にて `return_code_job1 = 1`,`return_code_job3 = 1`を指定すると、job1,job3,job4,job5 が実行される。<br>Order変数にて `return_code_job2 = 5`を指定すると、job1,job2,job4,job5 が実行される。<br>※リターンコードは書き換えていないため、各Jobのリターンコードは0となる   |
| 13_Synchronization/<br>jduNoticeDailyPlanExpect            | Notice Boardsのサンプル<br>これを実行することで、該当Notice Board`jduNoticeDailyPlan` にID`yyyy-mm-dd`のPost待ちで処理が待機となることを確認。<br>※ID`yyyy-mm-dd`はOrderIDから取得するが、UTCのTimeZoneから日付値をとるため、PostとExpectの実行タイミングによっては一致しないのでは？DailyPlanで実行される場合は該当日付値となる？   |
| 13_Synchronization/<br>jduNoticeDailyPlanPost              | 実行することで、Notice Board`jduNoticeDailyPlan` にID`yyyy-mm-dd`の通知を行う。これにより、`jduNoticeDailyPlanExpect`の待ち状態だった処理が実行されたことを確認。<br> ※RESOURCESより、NoticeBoardの通知状況の確認、既に通知されたIDの削除が可能<br>|
| 13_Synchronization/<br>jduNoticeDailyPlanOrderNameExpect   | 実行すると、 Notice Board`jduNoticeDailyPlan` のID通知待ちとなる。 `jduNoticeDailyPlanExpect`の実行で、Notice Board`jduNoticeDailyPlan` にID`yyyy-mm-dd`が通知されると、処理が進み、次に`jduNoticeDailyPlanOrderName`の通知待ちとなる。<br>`jduNoticeDailyPlanOrderNamePost` を実行して、`jduNoticeDailyPlanOrderName` にID `yyyy-mm-ddname`が通知されると、待ち状態だった処理が進むことを確認。|
| 13_Synchronization/<br>jduNoticeDailyPlanOrderNamePost     | 上記実行に必要。 |
| 14_Sequencing/<br>jduSequenceAddOrder_001                  | job1,job2の処理後、別WorkFlow`jduSequenceReceiveOrder`のOrderを登録。この際Order変数として `booking_code = BC45`, `flight_destination = London`が渡される。 `jduSequenceReceiveOrder`もあわせて実行されたことを確認。 |
| 14_Sequencing/<br>jduSequenceAddOrder_002                  | 001と同様。条件一致の場合のみ別WorkFlowのOrder登録をし、後続処理を実行。<br>※後続処理は、非同期（呼び出しWorkFlowの結果を待たず）実行されるため注意。    |
| 14_Sequencing/<br>jduSequenceReceiveOrder                  | 001、002より呼び出される処理 |
| 15_AdmissionTimes/<br>jduAdmissionTime_001                 | Admission Timeのサンプル<br>job2 にAdmission Time (水曜16時から2h、日曜13時から4h)が設定されており、  `Skip Job if no admission for Order day` にチェックがついている。<br><br>指定曜日の場合、指定時間外ならば待機、指定時間になると処理が流れる。<br>指定曜日以外の場合、job2はスキップされる。<br>※WorkFlowのTimeZoneをAsia/Tokyo（もしくは対象TimeZone）指定することを忘れずに！|


# その他
各種サンプルのOnlineデモの説明、Workflow定義の動画マニュアルは下記ページに掲載されています。
※online demoのみに存在するもの、本ページで説明したサンプルデータのみに存在するものがあります。

https://kb.sos-berlin.com/display/PKB/JS7+-+Online+Demo

https://kb.sos-berlin.com/display/PKB/JS7+-+Getting+Started