IBM Process Mining メモ - (5) BAWの情報の取り込み

# はじめに

BAW(Business Automation Workflow)のアクティビティー・ログをIBM Process Miningに取り込んで分析する流れを試してみます。
CP4BA(Cloud Pak for Business Automation)であれば、BAWの情報は分析ツールであるBAI(Business Automation Insight)に容易に連携できたりします。BAIはElasticsearchが使われているようなのでそこからデータを引っこ抜くことは割と簡単にできそうです。
ただ、BAW単体で構築している場合やBAIを使ってない環境だとその方法は使えません。
BAWでは各種操作を行うためのREST APIが提供されており、API経由でアクティビティーのログを取得することはできるようです。ただしここで取得されるデータ・フォーマットはJSON/XMLなので、そのままProcess Miningに食わせることはできません。
そのため、BAWからアクティビティー・ログを取得しCSVファイルに加工するGRUMPというツールがGitHub上に提供れています。

参考: [GitHub - GRUMP : BAW Extraction Utility](https://github.com/gerry-baird/grump)

ここでは、GRUMPというツールを使ってBAWからアクティビティー・ログを取得してCSV化しそれをIBM Process Serverに取り込む、ということを試してみます。

※このツールは適宜修正が入っていますが、この記事では2022/06/14以前のコードで試しています。(2022/6/15以降にUpdateが入っています)

## 関連記事

[IBM Process Mining メモ - (1) 概要](https://qiita.com/tomotagwork/items/bf187d6cd8346cb1a86b)
[IBM Process Mining メモ - (2) RHEL8へのインストール](https://qiita.com/tomotagwork/items/bea465ddc195cf06fbf7)
[IBM Process Mining メモ - (3) CSVの取り込みとモデル](https://qiita.com/tomotagwork/items/73cccfc58f5a8836683f)
[IBM Process Mining メモ - (4) BPMN](https://qiita.com/tomotagwork/items/ba07959e49afd95e24e8)
[IBM Process Mining メモ - (5) BAWの情報の取り込み](https://qiita.com/tomotagwork/items/90ca2ac6d100e4c26786)

# GRUMP概要

GRUMPの実体はPythonのスクリプトです。使い方は以下のYouTube動画も参考になると思います。
参考: [YouTube - BAW Process Mining : GRUMP](https://www.youtube.com/watch?v=YZXIsKJIy58)

Pythonのスクリプトで、BAWに対してREST APIを発行してアクティビティーに関する情報を取得します。そこで取得された情報をParseし、ProcessMiningにそのまま食わせられる形でCSVファイルとして出力します。

BAWのエンドポイントや取得対象のプロジェクト名はConfigファイルで指定することになります。業務固有のビジネス・データも取得したい場合はConfigファイルで指定すれば合わせて取得できるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/e86a782b-3789-5a4e-75e8-e0ea39d78af9.png)


# GRUMP使用手順例

## 事前準備 (BAW環境確認)

BAWのエンドポイントを確認しておきます。

ブラウザからBAWのエンドポイントに対して以下のAPIを発行してみます。
参考: [REST interface for BPD-related resources - Process Applications Resource - GET Method](https://www.ibm.com/docs/en/baw/20.x?topic=applications-get)

`https://host:port/rest/bpm/wlev1/processApps`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/a1ae5b69-1ab1-319a-bf5b-d51594919a45.png)

結果が返ればOKです。


今回取得するアクティビティ・ログは、サンプルとして提供されているHiring Sampleのものを使用したいと思います。上の結果から、"Hiring Sample"についての`<shortName>`、`<name>`の値を確認しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/763e49e3-d73c-f10d-3440-daf3705a42f1.png)


## 環境セットアップ

RHEL8上にGRUMPの稼働環境をセットアップしていきます。

### Pythonのセットアップ
GRUMPの実体はPythonのスクリプトなのでPython環境を整備します。
以下のサイトを参考に。
https://www.markaicode.com/ja/install-python-3-10-on-centos-rhel-8-fedora-35-34/
Python3.10.5を以下からダウンロードして使用します。
https://www.python.org/ftp/python/3.10.5/

ダウンロード

```
[root@Test13 /Inst_Image/Python310]# wget https://www.python.org/ftp/python/3.10.5/Python-3.10.5.tgz
--2022-06-08 17:45:06--  https://www.python.org/ftp/python/3.10.5/Python-3.10.5.tgz
www.python.org (www.python.org) をDNSに問いあわせています... 151.101.108.223, 2a04:4e42:1a::223
www.python.org (www.python.org)|151.101.108.223|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 25628472 (24M) [application/octet-stream]
`Python-3.10.5.tgz' に保存中

Python-3.10.5.tgz                                100%[========================================================================================================>]  24.44M  19.8MB/s 時間 1.2s

2022-06-08 17:45:08 (19.8 MB/s) - `Python-3.10.5.tgz' へ保存完了 [25628472/25628472]
```

解凍

```
[root@Test13 /Inst_Image/Python310]# tar xzf Python-3.10.5.tgz
```

config実行

```
[root@Test13 /Inst_Image/Python310]# cd Python-3.10.5/
[root@Test13 /Inst_Image/Python310/Python-3.10.5]# ./configure --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions

...
checking for stdatomic.h... yes
checking for builtin __atomic_load_n and __atomic_store_n functions... yes
checking for ensurepip... upgrade
checking if the dirent structure of a d_type field... yes
checking for the Linux getrandom() syscall... yes
checking for the getrandom() function... yes
checking for library containing shm_open... -lrt
checking for sys/mman.h... (cached) yes
checking for shm_open... yes
checking for shm_unlink... yes
checking for pkg-config... /usr/bin/pkg-config
checking whether compiling and linking against OpenSSL works... yes
checking for --with-openssl-rpath...
checking whether OpenSSL provides required APIs... yes
checking for --with-ssl-default-suites... python
checking for --with-builtin-hashlib-hashes... md5,sha1,sha256,sha512,sha3,blake2
checking for --with-experimental-isolated-subinterpreters... no
checking for --with-static-libpython... yes
checking for --disable-test-modules... no
configure: creating ./config.status
config.status: creating Makefile.pre
config.status: creating Misc/python.pc
config.status: creating Misc/python-embed.pc
config.status: creating Misc/python-config.sh
config.status: creating Modules/ld_so_aix
config.status: creating pyconfig.h
creating Modules/Setup.local
creating Makefile


If you want a release build with all stable optimizations active (PGO, etc),
please run ./configure --enable-optimizations
```

make実行

```
[root@Test13 /Inst_Image/Python310/Python-3.10.5]# make altinstall
...

copying build/scripts-3.10/idle3.10 -> /usr/local/bin
copying build/scripts-3.10/2to3-3.10 -> /usr/local/bin
changing mode of /usr/local/bin/pydoc3.10 to 755
changing mode of /usr/local/bin/idle3.10 to 755
changing mode of /usr/local/bin/2to3-3.10 to 755
rm /usr/local/lib/python3.10/lib-dynload/_sysconfigdata__linux_x86_64-linux-gnu.py
rm -r /usr/local/lib/python3.10/lib-dynload/__pycache__
/usr/bin/install -c -m 644 ./Misc/python.man \
        /usr/local/share/man/man1/python3.10.1
if test "xupgrade" != "xno"  ; then \
        case upgrade in \
                upgrade) ensurepip="--altinstall --upgrade" ;; \
                install|*) ensurepip="--altinstall" ;; \
        esac; \
         ./python -E -m ensurepip \
                $ensurepip --root=/ ; \
fi
Looking in links: /opt/processmining/repository/temp/tmpkno3776_
Processing /opt/processmining/repository/temp/tmpkno3776_/setuptools-58.1.0-py3-none-any.whl
Processing /opt/processmining/repository/temp/tmpkno3776_/pip-22.0.4-py3-none-any.whl
Installing collected packages: setuptools, pip
Successfully installed pip-22.0.4 setuptools-58.1.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
```

バージョン確認

```
[root@Test13 /Inst_Image/Python310/Python-3.10.5]# python3.10 -V
Python 3.10.5
[root@Test13 /Inst_Image/Python310/Python-3.10.5]# pip3.10 -V
wpip 22.0.4 from /usr/local/lib/python3.10/site-packages/pip (python 3.10)
[root@Test13 /Inst_Image/Python310/Python-3.10.5]# which python3.10
/usr/local/bin/python3.10
[root@Test13 /Inst_Image/Python310/Python-3.10.5]# which pip3.10
/usr/local/bin/pip3.10
```

### GRUMPのセットアップ
GRUMP自体のセットアップを行います。
基本的には以下GitHubのREADME, YouTube動画を参考に。
[GitHum - GRUMP : BAW Extraction Utility](https://github.com/gerry-baird/grump)
[YouTube - BAW Process Mining : GRUMP](https://www.youtube.com/watch?v=YZXIsKJIy58)

Git Clone

```
[root@Test13 /Grump]# git clone https://github.com/gerry-baird/grump.git
Cloning into 'grump'...
remote: Enumerating objects: 32, done.
remote: Counting objects: 100% (32/32), done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 32 (delta 15), reused 25 (delta 8), pack-reused 0
Unpacking objects: 100% (32/32), 8.68 KiB | 423.00 KiB/s, done.
[root@Test13 /Grump]# ls
grump
[root@Test13 /Grump/grump]# ls -la
合計 28
drwxr-xr-x. 3 root root   112  6月  8 18:05 .
drwxr-xr-x. 3 root root    19  6月  8 18:05 ..
drwxr-xr-x. 8 root root   163  6月  8 18:05 .git
-rw-r--r--. 1 root root  2771  6月  8 18:05 .gitignore
-rw-r--r--. 1 root root   956  6月  8 18:05 README.md
-rw-r--r--. 1 root root   495  6月  8 18:05 config.yaml
-rw-r--r--. 1 root root 10475  6月  8 18:05 grump.py
-rw-r--r--. 1 root root   390  6月  8 18:05 requirements.txt
```

手順ではPythonのVirtual Environmentなる機能を使っているようなのでそれに従います。
ちなみにVirtual Environmentについては以下も参考にさせていただきました。
参考: [venv: Python 仮想環境管理](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)

virtualenvインストール

```
[root@Test13 /Grump/grump]# pip3.10 install virtualenv
Collecting virtualenv
  Downloading virtualenv-20.14.1-py2.py3-none-any.whl (8.8 MB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 8.8/8.8 MB 17.3 MB/s eta 0:00:00
Collecting distlib<1,>=0.3.1
  Downloading distlib-0.3.4-py2.py3-none-any.whl (461 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 461.2/461.2 KB 16.3 MB/s eta 0:00:00
Collecting platformdirs<3,>=2
  Downloading platformdirs-2.5.2-py3-none-any.whl (14 kB)
Collecting six<2,>=1.9.0
  Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting filelock<4,>=3.2
  Downloading filelock-3.7.1-py3-none-any.whl (10 kB)
Installing collected packages: distlib, six, platformdirs, filelock, virtualenv
Successfully installed distlib-0.3.4 filelock-3.7.1 platformdirs-2.5.2 six-1.16.0 virtualenv-20.14.1
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 22.0.4; however, version 22.1.2 is available.
You should consider upgrading via the '/usr/local/bin/python3.10 -m pip install --upgrade pip' command.

[root@Test13 /Grump/grump]# virtualenv --version
virtualenv 20.14.1 from /usr/local/lib/python3.10/site-packages/virtualenv/__init__.py
```

virtualenv作成

```
[root@Test13 /Grump/grump]# virtualenv grumpy --python=python3.10
created virtual environment CPython3.10.5.final.0-64 in 1644ms
  creator CPython3Posix(dest=/Grump/grump/grumpy, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)
    added seed packages: pip==22.0.4, setuptools==62.1.0, wheel==0.37.1
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
```

Activate virtualenv

```
[root@Test13 /Grump/grump]# source grumpy/bin/activate

(grumpy) [root@Test13 /Grump/grump]# which python3
/Grump/grump/grumpy/bin/python3
(grumpy) [root@Test13 /Grump/grump]# which pip3
/Grump/grump/grumpy/bin/pip3
```

Install requirement

```
(grumpy) [root@Test13 /Grump/grump]# pip3 install -r requirements.txt
Collecting aiohttp==3.7.4.post0
  Downloading aiohttp-3.7.4.post0.tar.gz (1.1 MB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 1.1/1.1 MB 13.3 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Collecting async-timeout==3.0.1
  Downloading async_timeout-3.0.1-py3-none-any.whl (8.2 kB)
Collecting attrs==21.2.0
  Downloading attrs-21.2.0-py2.py3-none-any.whl (53 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 53.7/53.7 KB 8.7 MB/s eta 0:00:00
Collecting backports.entry-points-selectable==1.1.0
  Downloading backports.entry_points_selectable-1.1.0-py2.py3-none-any.whl (6.2 kB)
Collecting certifi==2021.10.8
  Downloading certifi-2021.10.8-py2.py3-none-any.whl (149 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 149.2/149.2 KB 14.0 MB/s eta 0:00:00
Collecting chardet==4.0.0
  Downloading chardet-4.0.0-py2.py3-none-any.whl (178 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 178.7/178.7 KB 20.0 MB/s eta 0:00:00
Collecting charset-normalizer==2.0.7
  Downloading charset_normalizer-2.0.7-py3-none-any.whl (38 kB)
Collecting decorator==5.1.0
  Downloading decorator-5.1.0-py3-none-any.whl (9.1 kB)
Collecting distlib==0.3.3
  Downloading distlib-0.3.3-py2.py3-none-any.whl (496 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 496.1/496.1 KB 17.0 MB/s eta 0:00:00
Collecting filelock==3.3.1
  Downloading filelock-3.3.1-py3-none-any.whl (9.7 kB)
Collecting idna==3.3
  Downloading idna-3.3-py3-none-any.whl (61 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 61.2/61.2 KB 8.3 MB/s eta 0:00:00
Collecting jsonpath-ng==1.5.3
  Downloading jsonpath_ng-1.5.3-py3-none-any.whl (29 kB)
Collecting multidict==5.2.0
  Downloading multidict-5.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (175 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 175.1/175.1 KB 12.8 MB/s eta 0:00:00
Collecting platformdirs==2.4.0
  Downloading platformdirs-2.4.0-py3-none-any.whl (14 kB)
Collecting ply==3.11
  Downloading ply-3.11-py2.py3-none-any.whl (49 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 49.6/49.6 KB 6.6 MB/s eta 0:00:00
Collecting PyYAML==6.0
  Downloading PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (682 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 682.2/682.2 KB 18.8 MB/s eta 0:00:00
Collecting requests==2.26.0
  Downloading requests-2.26.0-py2.py3-none-any.whl (62 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 62.3/62.3 KB 7.4 MB/s eta 0:00:00
Collecting six==1.16.0
  Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting tqdm==4.62.3
  Downloading tqdm-4.62.3-py2.py3-none-any.whl (76 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 76.2/76.2 KB 5.5 MB/s eta 0:00:00
Collecting typing-extensions==3.10.0.2
  Downloading typing_extensions-3.10.0.2-py3-none-any.whl (26 kB)
Collecting urllib3==1.26.7
  Downloading urllib3-1.26.7-py2.py3-none-any.whl (138 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 138.8/138.8 KB 11.5 MB/s eta 0:00:00
Collecting yarl==1.7.0
  Downloading yarl-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (305 kB)
     qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 305.2/305.2 KB 14.9 MB/s eta 0:00:00
Building wheels for collected packages: aiohttp
  Building wheel for aiohttp (pyproject.toml) ... done
  Created wheel for aiohttp: filename=aiohttp-3.7.4.post0-cp310-cp310-linux_x86_64.whl size=1375282 sha256=73c30fbdf2c871115a8736c03a582397c82f20b7ec0865cb1985aad7c5f4e19d
  Stored in directory: /root/.cache/pip/wheels/fc/84/e0/52113c57eb9b09b6b187a0f369eaad6fc7fc64bb7247c83b89
Successfully built aiohttp
Installing collected packages: typing-extensions, ply, distlib, certifi, urllib3, tqdm, six, PyYAML, platformdirs, multidict, idna, filelock, decorator, charset-normalizer, chardet, backports.entry-points-selectable, attrs, async-timeout, yarl, requests, jsonpath-ng, aiohttp
Successfully installed PyYAML-6.0 aiohttp-3.7.4.post0 async-timeout-3.0.1 attrs-21.2.0 backports.entry-points-selectable-1.1.0 certifi-2021.10.8 chardet-4.0.0 charset-normalizer-2.0.7 decorator-5.1.0 distlib-0.3.3 filelock-3.3.1 idna-3.3 jsonpath-ng-1.5.3 multidict-5.2.0 platformdirs-2.4.0 ply-3.11 requests-2.26.0 six-1.16.0 tqdm-4.62.3 typing-extensions-3.10.0.2 urllib3-1.26.7 yarl-1.7.0
WARNING: You are using pip version 22.0.4; however, version 22.1.2 is available.
You should consider upgrading via the '/Grump/grump/grumpy/bin/python -m pip install --upgrade pip' command.
```

Deactivate virtualenv

```
(grumpy) [root@Test13 /Grump/grump]# deactivate
```

これで一通りGRUMP環境は整いました。

## GRUMPによるBAWのアクティビティー・ログ取得

実際にGRUMPを使ってBAWからアクティビティー・ログを取得してみます。
まず構成ファイルを編集します。

```yaml:config.yaml
# Mandatory config
user: admin
password: admin
root-url: https://host:port/

project: HSS
process-name: Hiring Sample
thread-count: 1

# Optional config
instance-limit: 500
modified-after :
modified-before :
business-data:
#   - name: #country
#     path: #$..*.domicileCountry
#   - name: #reason
#     path: #$..*.Offboarding_Request.reasonType
#   - name: #gender
#     path: #$..*.Offboarding_Request.subject.*.gender
```

BAWにアクセスするためのURL、ユーザーID/パスワード、取得対象のプロジェクト情報などを指定します。
project、process-nameには、それぞれ先に確認した`<shortName>`、`<name>`を指定します。
(※process-nameは実は何をしても意味が無いっぽいが、無指定だとpythonスクリプトがエラーになるのでとりあえずここではnameの値を指定しています。詳細は後述。)
今回はビジネス・データについては取得しないので、business-data:以下はコメントアウトします。
取得対象のログの範囲を`modified-after`, `modified-before`で指定できます(日時指定)。今回は全情報取得するのでブランクにしておきます。


Activate virtualenv

```
[root@Test13 /Grump/grump]# source grumpy/bin/activate
(grumpy) [root@Test13 /Grump/grump]#
```

GRUMP実行

```
(grumpy) [root@Test13 /Grump/grump]# python3 grump.py -c config.yaml
GRUMP : Starting
Found : 10 instances of BPD Hiring Sample in project HSS
Processing 10 instances. Fetching task summaries .....
100%|?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????| 10/10 [00:01<00:00,  6.68it/s]
Processing 31 tasks. Fetching task details .....
100%|?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????| 31/31 [00:03<00:00,  7.96it/s]
GRUMP Finished
--- 6.15579080581665 seconds ---
```

結果確認⇒ `data_file.csv`というファイルが作成されている

```
(grumpy) [root@Test13 /Grump/grump]# ls -la
合計 96
drwxr-xr-x. 4 root root  4096  6月  8 22:02 .
drwxr-xr-x. 3 root root    19  6月  8 18:05 ..
drwxr-xr-x. 8 root root   163  6月  8 18:05 .git
-rw-r--r--. 1 root root  2771  6月  8 18:05 .gitignore
-rw-r--r--. 1 root root   956  6月  8 18:05 README.md
-rw-r--r--. 1 root root   446  6月  8 22:02 config.yaml
-rw-r--r--. 1 root root   495  6月  8 18:30 config.yaml.org
-rw-r--r--. 1 root root  3146  6月  8 22:02 data_file.csv
-rw-r--r--. 1 root root 29438  6月  8 22:02 grump.log
-rw-r--r--. 1 root root  4037  6月  8 19:20 grump.log.bk
-rw-r--r--. 1 root root 10496  6月  8 19:24 grump.py
-rw-r--r--. 1 root root 10475  6月  8 19:15 grump.py.org
drwxr-xr-x. 4 root root    64  6月  8 18:23 grumpy
-rw-r--r--. 1 root root   390  6月  8 18:05 requirements.txt
```

出力されたCSVファイルの中身確認

```csv:data_file.csv
processID,taskID,Task Name,Start,End,Team,Owner
5904,7114,Find position candidates,2022-06-08T11:47:48Z,2022-06-08T11:48:19Z,Human Resources,admin
5803,7005,Find position candidates,2022-02-15T12:52:31Z,2022-02-15T12:52:38Z,Human Resources,admin
5753,6955,Find position candidates,2022-02-04T14:57:55Z,2022-02-04T14:58:01Z,Human Resources,admin
5703,6905,Find position candidates,2022-02-03T15:43:05Z,2022-02-03T15:43:11Z,Human Resources,dadmin
5653,6855,Find position candidates,2021-10-12T13:49:13Z,2021-10-12T13:49:19Z,Human Resources,admin
5504,6760,Find position candidates,2021-10-04T14:43:28Z,2021-10-04T14:43:34Z,Human Resources,admin
5454,6757,Find position candidates,2021-10-04T10:10:57Z,2021-10-04T10:11:12Z,Human Resources,admin
5453,6756,Find position candidates,2021-10-04T10:10:45Z,2021-10-04T10:11:07Z,Human Resources,admin
5455,6710,Find position candidates,2021-08-26T16:17:46Z,2021-10-04T10:11:02Z,Human Resources,admin
5503,6755,Find position candidates,2021-10-04T10:10:27Z,2021-10-04T10:10:38Z,Human Resources,admin
5904,7113,Review new position request,2022-06-08T11:46:13Z,2022-06-08T11:47:48Z,GeneralManagers,admin
5803,7004,Review new position request,2022-02-15T12:52:11Z,2022-02-15T12:52:31Z,GeneralManagers,admin
5753,6954,Review new position request,2022-02-04T14:57:48Z,2022-02-04T14:57:54Z,GeneralManagers,admin
5703,6904,Review new position request,2022-02-03T15:42:58Z,2022-02-03T15:43:05Z,GeneralManagers,dadmin
5653,6854,Review new position request,2021-10-12T13:49:06Z,2021-10-12T13:49:12Z,GeneralManagers,admin
5504,6759,Review new position request,2021-10-04T13:35:45Z,2021-10-04T14:43:28Z,GeneralManagers,admin
5454,6707,Review new position request,2021-08-26T15:56:56Z,2021-10-04T10:10:56Z,GeneralManagers,admin
5453,6705,Send escalation notice,2021-08-26T14:33:46Z,2021-08-26T14:33:47Z,,dadmin
5455,6709,Review new position request,2021-08-26T16:17:39Z,2021-08-26T16:17:46Z,GeneralManagers,admin
5503,6754,Review new position request,2021-10-04T10:10:12Z,2021-10-04T10:10:27Z,GeneralManagers,admin
5904,7112,Submit position request,2022-06-08T11:45:37Z,2022-06-08T11:46:12Z,HiringManagers,admin
5803,7003,Submit position request,2022-02-15T12:50:37Z,2022-02-15T12:52:11Z,HiringManagers,admin
5753,6953,Submit position request,2022-02-04T14:57:23Z,2022-02-04T14:57:48Z,HiringManagers,admin
5703,6903,Submit position request,2022-02-03T15:40:14Z,2022-02-03T15:42:58Z,HiringManagers,dadmin
5653,6853,Submit position request,2021-10-12T13:48:36Z,2021-10-12T13:49:05Z,HiringManagers,admin
5504,6758,Submit position request,2021-10-04T13:35:37Z,2021-10-04T13:35:45Z,HiringManagers,admin
5454,6706,Submit position request,2021-08-26T15:56:42Z,2021-08-26T15:56:55Z,HiringManagers,admin
5453,6704,Review new position request,2021-07-26T14:28:28Z,2021-10-04T10:10:44Z,GeneralManagers,admin
5455,6708,Submit position request,2021-08-26T16:17:27Z,2021-08-26T16:17:38Z,HiringManagers,admin
5503,6753,Submit position request,2021-10-04T10:09:32Z,2021-10-04T10:10:11Z,HiringManagers,admin
5453,6703,Submit position request,2021-07-26T14:27:58Z,2021-07-26T14:28:27Z,HiringManagers,admin
```

Deativate virtualenv

```
(grumpy) [root@Test13 /Grump/grump]# deactivate
[root@Test13 /Grump/grump]#
```

## IBM Process Miningへのデータ取り込み

前の記事の手順に従って、GRUMPで取得したCSVファイルをProcess Miningに取り込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/6878dfdf-049b-2f3a-b1f0-c69c329f81ac.png)

このように可視化できることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/b7743571-2830-4730-8db4-e3b7d2c39f18.png)

BAW上で実行されたワークフローのActivityログをGRUMPというツールによって取得しIBM Process Miningで分析するまでの一連の流れを確認できました。


# GRUMP補足

## REST API

grump.pyではBAWに対して以下のようなREST APIが発行されていました。

**(1)インスタンス・リスト取得**
例: `https://host:port/rest/bpm/wle/v1/processes/search?modifiedAfter=2021-10-04T10:11:00Z&modifiedBefore=2022-06-08T11:48:00Z&projectFilter=HSS&limit=500`

参考: [REST interface for BPD-related resources - Process Instances Search Resource - GET Method](https://www.ibm.com/docs/en/baw/20.x?topic=search-get)

**(2)取得した各インスタンスごとにtaskSummary情報(Task情報)を取得** (Fetching task summaries for bpd instance : 5803)
例: `https://host:port/rest/bpm/wle/v1/process/5803/taskSummary/`
※5083は(1)で取得したインスタンスIDの例

参考: [REST interface for BPD-related resources - Process Instance Task Summary Resource - GET Method](https://www.ibm.com/docs/en/baw/20.x?topic=summary-get)

**(3)各インスタンスのTaskごとの詳細情報を取得** (Fetching task details for bpd instance : 5803 and Task : 7005)
例: `https://host:port/rest/bpm/wle/v1/task/7005?parts=data`
※7005は(2)で取得したタスクIDの例

参考: [REST interface for BPD-related resources - Task Instance Resource - GET Method](https://www.ibm.com/docs/en/baw/20.x?topic=ti-get)

## 構成ファイル
構成ファイルの指定方法について補足です。

### process-name

```yaml:config.yaml
# Mandatory config
user: admin
password: admin
root-url: https://host:port/

project: HSS
process-name: Hiring Sample
thread-count: 1

# Optional config
instance-limit: 500
modified-after :
modified-before :
business-data:
#   - name: #country
#     path: #$..*.domicileCountry
#   - name: #reason
#     path: #$..*.Offboarding_Request.reasonType
#   - name: #gender
#     path: #$..*.Offboarding_Request.subject.*.gender
```

上に示したconfig.yamlを作成してPythonスクリプト実行すると、最初に以下のようなREST APIが発行されます(host, portは実際のエンドポイントに置き換えてください)。

`https://host:port/rest/bpm/wle/v1/processes/search?Hiring Sample&projectFilter=HSS&limit=500`

URLの末尾の"?"以降はQuery Parameterを意味しますが、"process-name"に指定した値がうまく渡せていませんね。なのでこの指定は効果が無いはず。元のPython ScriptのURL組み立てるところのロジックのバグっぽいです。
指定しないとURLのSyntaxがおかしくなるのでとりあえず任意の文字列いれておけばよいでしょう。
(気持ち悪いですが面倒なので放置します。)

### modified-after / modified-before

config.yamlのmodified-after/modified-biforeを指定することで、取得するログの日時での範囲指定ができます。


```yaml:config.yaml
# Mandatory config
user: admin
password: admin
root-url: https://host:port/

project: HSS
process-name: Hiring Sample
thread-count: 1

# Optional config
instance-limit: 500
modified-after : 2021-10-04T10:11:00Z
modified-before : 2022-06-08T11:48:00Z
business-data:
#   - name: #country
#     path: #$..*.domicileCountry
#   - name: #reason
#     path: #$..*.Offboarding_Request.reasonType
#   - name: #gender
#     path: #$..*.Offboarding_Request.subject.*.gender
```

上に示したconfig.yamlを作成してPythonスクリプト実行すると、最初に以下のようなREST APIが発行されます(host, portは実際のエンドポイントに置き換えてください)。

`https://host:port/rest/bpm/wle/v1/processes/search?modifiedAfter=2021-10-04T10:11:00Z&modifiedBefore=2022-06-08T11:48:00Z&Hiring Sample&projectFilter=HSS&limit=500`

modified-after ～ modified-before の日時の範囲のログのみ取得されます。

```csv:data_file.csv
processID,taskID,Task Name,Start,End,Team,Owner
5803,7005,Find position candidates,2022-02-15T12:52:31Z,2022-02-15T12:52:38Z,Human Resources,admin
5753,6955,Find position candidates,2022-02-04T14:57:55Z,2022-02-04T14:58:01Z,Human Resources,admin
5703,6905,Find position candidates,2022-02-03T15:43:05Z,2022-02-03T15:43:11Z,Human Resources,dadmin
5653,6855,Find position candidates,2021-10-12T13:49:13Z,2021-10-12T13:49:19Z,Human Resources,admin
5504,6760,Find position candidates,2021-10-04T14:43:28Z,2021-10-04T14:43:34Z,Human Resources,admin
5454,6757,Find position candidates,2021-10-04T10:10:57Z,2021-10-04T10:11:12Z,Human Resources,admin
5453,6756,Find position candidates,2021-10-04T10:10:45Z,2021-10-04T10:11:07Z,Human Resources,admin
5455,6710,Find position candidates,2021-08-26T16:17:46Z,2021-10-04T10:11:02Z,Human Resources,admin
5803,7004,Review new position request,2022-02-15T12:52:11Z,2022-02-15T12:52:31Z,GeneralManagers,admin
5753,6954,Review new position request,2022-02-04T14:57:48Z,2022-02-04T14:57:54Z,GeneralManagers,admin
5703,6904,Review new position request,2022-02-03T15:42:58Z,2022-02-03T15:43:05Z,GeneralManagers,dadmin
5653,6854,Review new position request,2021-10-12T13:49:06Z,2021-10-12T13:49:12Z,GeneralManagers,admin
5504,6759,Review new position request,2021-10-04T13:35:45Z,2021-10-04T14:43:28Z,GeneralManagers,admin
5454,6707,Review new position request,2021-08-26T15:56:56Z,2021-10-04T10:10:56Z,GeneralManagers,admin
5453,6705,Send escalation notice,2021-08-26T14:33:46Z,2021-08-26T14:33:47Z,,dadmin
5455,6709,Review new position request,2021-08-26T16:17:39Z,2021-08-26T16:17:46Z,GeneralManagers,admin
5803,7003,Submit position request,2022-02-15T12:50:37Z,2022-02-15T12:52:11Z,HiringManagers,admin
5753,6953,Submit position request,2022-02-04T14:57:23Z,2022-02-04T14:57:48Z,HiringManagers,admin
5703,6903,Submit position request,2022-02-03T15:40:14Z,2022-02-03T15:42:58Z,HiringManagers,dadmin
5653,6853,Submit position request,2021-10-12T13:48:36Z,2021-10-12T13:49:05Z,HiringManagers,admin
5504,6758,Submit position request,2021-10-04T13:35:37Z,2021-10-04T13:35:45Z,HiringManagers,admin
5454,6706,Submit position request,2021-08-26T15:56:42Z,2021-08-26T15:56:55Z,HiringManagers,admin
5453,6704,Review new position request,2021-07-26T14:28:28Z,2021-10-04T10:10:44Z,GeneralManagers,admin
5455,6708,Submit position request,2021-08-26T16:17:27Z,2021-08-26T16:17:38Z,HiringManagers,admin
5453,6703,Submit position request,2021-07-26T14:27:58Z,2021-07-26T14:28:27Z,HiringManagers,admin
```

modified-after / modified-beforeで指定した日時は、先の結果のCSVと見比べると 各イベントのEndの時刻を見てフィルターをかけている感じですね。

### business-data

業務固有の変数についても必要に応じてCSVのフィールドとして抽出することができます。
例えば、requisition以下の`empType`、replacement以下の`payType`、 candidates以下の`experience` の3つの変数を取得してみます。
REST APIで取得されるデータはJSON形式になっているので、JSONPathを指定して該当のフィールドを指定できます。

```yaml:config.yaml
# Mandatory config
user: admin
password: admin
root-url: https://host:port/

project: HSS
process-name: Hiring Sample
thread-count: 1

# Optional config
instance-limit: 500
modified-after : 2021-10-04T10:11:00Z
modified-before : 2022-06-08T11:48:00Z
business-data:
   - name: empType
     path: $..*.empType
   - name: payType
     path: $..*.payType
   - name: experience
     path: $..*.experience
```

上のようにconfig指定してGRUMP実行すると、以下のようなCSVが生成されます。

```csv:data-file.csv
processID,taskID,Task Name,Start,End,Team,Owner,empType,payType,experience
5803,7005,Find position candidates,2022-02-15T12:52:31Z,2022-02-15T12:52:38Z,Human Resources,admin,,Exempt,3-4 years experience
5753,6955,Find position candidates,2022-02-04T14:57:55Z,2022-02-04T14:58:01Z,Human Resources,admin,,Exempt,3-4 years experience
5703,6905,Find position candidates,2022-02-03T15:43:05Z,2022-02-03T15:43:11Z,Human Resources,dadmin,,Exempt,3-4 years experience
5653,6855,Find position candidates,2021-10-12T13:49:13Z,2021-10-12T13:49:19Z,Human Resources,admin,,Exempt,3-4 years experience
5504,6760,Find position candidates,2021-10-04T14:43:28Z,2021-10-04T14:43:34Z,Human Resources,admin,,Exempt,3-4 years experience
5454,6757,Find position candidates,2021-10-04T10:10:57Z,2021-10-04T10:11:12Z,Human Resources,admin,,Exempt,3-4 years experience
5453,6756,Find position candidates,2021-10-04T10:10:45Z,2021-10-04T10:11:07Z,Human Resources,admin,,Exempt,3-4 years experience
5455,6710,Find position candidates,2021-08-26T16:17:46Z,2021-10-04T10:11:02Z,Human Resources,admin,,Exempt,3-4 years experience
5803,7004,Review new position request,2022-02-15T12:52:11Z,2022-02-15T12:52:31Z,GeneralManagers,admin,Full-time,Exempt,
5753,6954,Review new position request,2022-02-04T14:57:48Z,2022-02-04T14:57:54Z,GeneralManagers,admin,Part-time,Exempt,
5703,6904,Review new position request,2022-02-03T15:42:58Z,2022-02-03T15:43:05Z,GeneralManagers,dadmin,Contract,Exempt,
5653,6854,Review new position request,2021-10-12T13:49:06Z,2021-10-12T13:49:12Z,GeneralManagers,admin,Contract,Exempt,
5504,6759,Review new position request,2021-10-04T13:35:45Z,2021-10-04T14:43:28Z,GeneralManagers,admin,Contract,Exempt,
5454,6707,Review new position request,2021-08-26T15:56:56Z,2021-10-04T10:10:56Z,GeneralManagers,admin,Contract,Exempt,
5453,6705,Send escalation notice,2021-08-26T14:33:46Z,2021-08-26T14:33:47Z,,dadmin,,,
5455,6709,Review new position request,2021-08-26T16:17:39Z,2021-08-26T16:17:46Z,GeneralManagers,admin,Contract,Exempt,
5803,7003,Submit position request,2022-02-15T12:50:37Z,2022-02-15T12:52:11Z,HiringManagers,admin,Full-time,Exempt,
5753,6953,Submit position request,2022-02-04T14:57:23Z,2022-02-04T14:57:48Z,HiringManagers,admin,Part-time,Exempt,
5703,6903,Submit position request,2022-02-03T15:40:14Z,2022-02-03T15:42:58Z,HiringManagers,dadmin,Contract,Exempt,
5653,6853,Submit position request,2021-10-12T13:48:36Z,2021-10-12T13:49:05Z,HiringManagers,admin,Contract,Exempt,
5504,6758,Submit position request,2021-10-04T13:35:37Z,2021-10-04T13:35:45Z,HiringManagers,admin,Contract,Exempt,
5454,6706,Submit position request,2021-08-26T15:56:42Z,2021-08-26T15:56:55Z,HiringManagers,admin,Contract,Exempt,
5453,6704,Review new position request,2021-07-26T14:28:28Z,2021-10-04T10:10:44Z,GeneralManagers,admin,Contract,Exempt,
5455,6708,Submit position request,2021-08-26T16:17:27Z,2021-08-26T16:17:38Z,HiringManagers,admin,Contract,Exempt,
5453,6703,Submit position request,2021-07-26T14:27:58Z,2021-07-26T14:28:27Z,HiringManagers,admin,Contract,Exempt,
```

末尾の列に、empType、payType、experienceのフィールドが追加されました。
IBM Process Miningに取り込む時にカスタム・フィールドとして取得したい変数はこのように抽出することが可能です。


# メモ
色々試しているあいだに、Grumpのソースに以下のような変更が入ってしましました。
https://github.com/gerry-baird/grump/commit/ccb1f91169f0cba2e082a57945428bbac3f93f50
ここではなぜかプロジェクトのフィルターがはずされています。
これだとフィルターが機能しなくなってしまう...