Watson AssistantとDb2を外部連係する

Watson Assistantは[こちら](https://qiita.com/schiyoda/items/bceabe327a0c7d08e9e4)の記事に記載の通り、IBM Cloud Function(ICF)経由で外部のサービスと連係することが可能です。本記事ではICF経由で Db2 on Cloudと連係する手順を紹介します。

# 前提
IBM Cloudで以下のサービスを作成しておきます。

- Watson Assistant
- Db2 

作成したDb2の資格情報(Credential)を生成し、**dsn** をメモしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/1422e52e-d1fd-f1af-b32b-6b790439ba67.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/04348295-8580-bcfc-2f01-9fb65bd29eac.png)

サンプル用のデータ [CUSTOMER.csv](https://raw.githubusercontent.com/schiyoda/ICF-Db2-Integration/master/CUSTOMER.csv) をダウンロードして、Db2にロードします。
**Open console** をクリックし、Db2のコンソールを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/1c548f73-8273-55ed-0279-40c674561d92.png)

左上のメニューから **LOAD** を選択し、ダウンロードしたCUSTOMER.csvをロードします。スキーマはデフォルトで作成されているスキーマ名を選択、テーブルは **CUSTOMER** を新規作成しています。その他設定はデフォルトのままロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/7b39aa2f-9eab-ae31-7d6b-3a0e137fae3d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/b08f7d08-1e8c-6ac4-090a-cb59bcab830a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/405c09c5-69cc-1959-831c-869147dbb5a0.png)







# IBM Cloud Function で Actionの作成
今回は先ほど作成したCUSTOMER表をCODEをキーにQueryするActionを作成します。

IBM Cloud画面右上のメニューから **Functions** を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/936d797e-1836-f597-42d4-c505947fe139.png)

適当な **組織-スペース** が選択されていことを確認し、**作成の開始** を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/8412c6cb-f665-4477-c317-f46e3a5f00d9.png)

**アクションの作成** をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/85d97f45-687a-cd6a-3048-5ee365609349.png)

アクション名を入力し、ランタイムで **python 3** を選択して **作成** をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/63bb4d48-da8c-ba2a-f57a-dec234b3f937.png)


以下のようにコードを入力し、**保存**します。（スキーマ名はDb2の環境に合わせて変更、connectの引数には先の手順で確認した **dsn** の値を使用します）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/fcaf81be-3902-7df1-0927-77a7829bf995.png)


```python
import sys
import ibm_db

def main(dict):
    rows = []
    conn = ibm_db.connect("DATABASE=BLUDB;HOSTNAME=dashdb-txn-sbox-yp-dal09-04.services.dal.bluemix.net;PORT=50000;PROTOCOL=TCPIP;UID=shw72782;PWD=xxxxxxxxx;","","")
    sql = 'SELECT LAST_NAME, FIRST_NAME, STATUS FROM SHW72782.CUSTOMER WHERE CODE={}'.format(dict["code"])
    stmt = ibm_db.exec_immediate(conn, sql)
    row = ibm_db.fetch_tuple(stmt)
    
    while (row):
        rows.append(row)
        row = ibm_db.fetch_tuple(stmt)
    
    return { 'result': rows }
```
**入力の変更** をクリックして、以下のようにテスト用の値を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/0ff5fef6-95d5-4062-d815-4b60770d623f.png)

**起動** をクリックして、結果が返って来たら正しく設定されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/621aa040-9646-5aee-0025-8bc337a86f83.png)

# Assistantの設定
ここでは、Assistantとの会話の開始時に、カスタマーID（CODE）が聞かれるので、入力するとDb2から該当のカスタマー情報を取得して応答する、という処理を実装します。

Entity <span>@</span>CustomerInfo を以下のように作成します。CustomerIDが4桁の数字であるとして、Patternで設定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/46967a82-5126-986e-9c00-d5be359861c2.png)

最初の **ようこそ** ノードで応答文を入力します。また、ICFに接続するためのCredentialをコンテキスト変数 $icf_cred に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/149e23b7-613b-2c8a-abf5-83c804fad206.png)

```JavaScript:$icf_cred
{"user":"7cc67d8a-14fe-4285-8bee-ff73bf93c5b7","password":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
```

>ICFのCredentialはDialogの中にハードコードしない方が望ましですが、ここでは簡単のため **ようこそ** ノードに設定することにします。
　

　　
>ICFのCredentialはICFの **Namespace Settings** タブで確認可能です。:(コロン)で区切られたAPIキーの前半がusername、後半がpasswordになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/eed19c80-8802-465b-54a6-8e403c018b91.png)

子ノードを作成し条件には <span>@</span>CustomerInfo:CustomerID を設定、JSONエディターでICFを呼び出すための設定をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/7610fdcd-bd85-0907-82ef-365b42631f9c.png)

```JavaScript
{
  "output": {
    "generic": []
  },
  "actions": [
    {
      "name": "/scorg01_dev/Customer",
      "type": "server",
      "parameters": {
        "code": "@CustomerInfo.literal"
      },
      "credentials": "$icf_cred",
      "result_variable": "context.customer_result"
    }
  ]
}
```

さらに子ノードを作成します。親ノードで **Jump to** を選択し、子ノードの **Respond** を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/8e6b0582-46da-5759-67bb-fb32ab063bda.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/2550f852-47c5-0dbc-5a69-dfb2c7b46c3d.png)

以下のように応答文を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/025ada66-1944-2b4d-25ab-81f2fffbb452.png)

**Try it** でテストします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/5c9a2097-9504-9bd8-b448-a89f9aca3771.png)

Db2からデータを取得し、Assistantで応答できることが確認できました。