Yellowfin PHP + REST API データソース追加

## はじめに
これまでも、[『SSO』](https://qiita.com/ExtremeCarvFJ/items/989a3c2bfa34ccdd177f)、[『情報参照』](https://qiita.com/ExtremeCarvFJ/items/0d3d9005b03e917ad839)、[『ユーザー登録』](https://qiita.com/ExtremeCarvFJ/items/1ddf337a6b24a948dc1e)、[『グループメンバー登録』]( https://qiita.com/ExtremeCarvFJ/items/dbd0f8a0722e2bfe06d7)など、Yellowfin の管理に REST API を活用する方法を幾つか紹介してきました。今回は、データソース追加に REST APIを活用する方法を紹介します。

## REST API 開発者用ドキュメントと動作検証
Yellowfin の REST API に関する詳細な情報は、[開発者サイト](https://developers.yellowfinbi.com/dev/api-docs/current/)に記述があります。
上記で API の仕様を確認した後、ブラウザのディベロッパーツールなどで、リクエストする情報と、レスポンスの情報が正しいか否かを確認しましょう。Chrome の場合だと、API Tester が該当します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/4476af32-5095-756b-2fc0-0b30d0d7e8f4.png)

## 追加するデータソース情報の準備
追加するデータソース情報を、下記例のように JSON の形式で記述します。下記は、PostgreSQL 上のデータベースに接続するための情報で、各項目の詳細に関しては、開発者ドキュメントの [Create a new data source](https://developers.yellowfinbi.com/dev/api-docs/current/#operation/createDataSource) に詳細説明があります。

```json:dataSource.txt
{
   "sourceName": "demo",
   "sourceDescription": "デモデータへの接続",
   "sourceType": "POSTGRESQL",
   "connectionType": "JDBC",
   "connectionTypeCode": "GENERICUSER",
   "connectionDriver": "org.postgresql.Driver",
   "connectionPath":"public",
   "connectionTimeout": 180,
   "userName": "postgres",
   "userPassword": "password",
   "minimumConnections": 1,
   "maximumConnections": 5,
   "refreshTime": 3,
   "timezone": "ASIA/TOKYO",
   "accessLevelCode": "UNSECURE",
   "maxRows": 10000,
   "maxAnalysisRows": 0,
   "inheritChildSourceFilters": false,
   "sourceOptions": [
      {
         "optionKey": "HOSTNAME",
         "optionValue": "localhost",
         "valueDataType": "2"
      },
      {
         "optionKey": "PORT",
         "optionValue": "5432",
         "valueDataType": "1"
      },
      {
         "optionKey": "DATABASE",
         "optionValue": "demo",
         "valueDataType": "2"
      },
      {
         "optionKey": "USESCHEMA",
         "optionValue": "true",
         "valueDataType": "6"
      }
   ]
}
```

とはいえ、各項目を確認するのも大変ですよね。
GUI から新規で PostgreSQL に接続する際に、上記と同じ設定を施した例が以下になります。
JSON には必要事項がたくさん記述されていますが、実際にデータベース毎に値を変えなければいけいない個所は、GUI で設定する個所だと考えていただけると良いかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/ade77f02-15cd-2b2c-bf0e-ec0e87b50cd7.png)

## アクセストークンの取得
ここからプログラムの内容に入ります。
Yellowfin のリソースにアクセスするために、2 種類のトークンを使用します。
1 つ目はリフレッシュトークンです。有効期限の無いトークンで、アクセストークンを取得するために必ず必要です。refresh-tokens API に対してリフレッシュトークンを POST で要求し取得します。
2 つ目はアクセストークンです。access-tokens API に対して入手済みのリフレッシュトークンを使って、POST で要求し取得します。
アクセストークンの取得に関する詳細は、[『情報参照』](https://qiita.com/ExtremeCarvFJ/items/0d3d9005b03e917ad839)記事の該当箇所をご確認ください。

## データソース追加
先の手順で取得したトークンを用いて、POST でデータソースを追加します。HEADER や BODY に必要な情報に関しては、開発者用ドキュメントの [Create a new data source](https://developers.yellowfinbi.com/dev/api-docs/current/#operation/createDataSource) で詳細をご確認ください。
以下のサンプルコードでは、cURL を使って作成した HEADER 情報と、読み込んだデータソースの情報で追加処理を行います。

```php: データソース追加
//変数の宣言
$time2 = ceil(microtime(true)*1000);
$url3 = 'http://localhost:8080/api/data-sources';

//データソース作成：HEADERデータ作成
$header3 = array(
	'Authorization:YELLOWFIN ts='.$time2.', nonce=123, token='.$accessToken,
	'Accept:application/vnd.yellowfin.api-v2+json',
	'Content-Type:application/json;charset=UTF-8'
);

//データソース定義読み込み
ob_start();
include("dataSource.json");
$datasource = ob_get_clean();

//データソース作成：BODYデータ作成
$ch3 = curl_init();
curl_setopt($ch3, CURLOPT_HTTPHEADER, $header3);
curl_setopt($ch3, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch3, CURLOPT_POSTFIELDS, $datasource);
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch3, CURLOPT_URL, $url3);
$result3 =curl_exec($ch3);
curl_close($ch3);
```

## データソース追加プログラム全容
データソース追加プログラムの全容は以下の通りです。
```php:addDatasource.php
//変数の宣言
$adminId = 'admin@yellowfin.com.au';
$adminPassword = 'test';
$time = ceil(microtime(true)*1000);
$url = 'http://localhost:8080/api/refresh-tokens';
$url2 = 'http://localhost:8080/api/access-tokens';
$refreshToken = "";
$accessToken = "";

//リフレッシュトークン：HEADERデータ作成
$header = array(
	'Authorization:YELLOWFIN ts='.$time.', nonce=123',
	'Accept:application/vnd.yellowfin.api-v2+json',
	'Content-Type:application/json;charset=UTF-8'
);

//リフレッシュトークン：BODYデータ作成
$body = array(
	'userName'=>$adminId,
	'password'=>$adminPassword
);
$body_json = json_encode($body, JSON_PRETTY_PRINT);

//リフレッシュトークン：Yellowfinにトークンを要求
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $body_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
$json_result = json_decode($result);
$refreshToken = $json_result->securityToken;
curl_close($ch);

//アクセストークン：HEADERデータ作成
$header2 = array(
	'Authorization:YELLOWFIN ts='.$time.', nonce=123, token='.$refreshToken,
	'Accept:application/vnd.yellowfin.api-v2+json',
	'Content-Type:application/json'
);

//アクセストークン：Yellowfinにトークンを要求
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_HTTPHEADER, $header2);
curl_setopt($ch2, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch2, CURLOPT_POSTFIELDS, '');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_URL, $url2);
curl_close($ch);
$result2 = curl_exec($ch2);
$json_result2 = json_decode($result2);
$accessToken=$json_result2->securityToken;

//変数の宣言
$time2 = ceil(microtime(true)*1000);
$url3 = 'http://localhost:8080/api/data-sources';

//データソース作成：HEADERデータ作成
$header3 = array(
	'Authorization:YELLOWFIN ts='.$time2.', nonce=123, token='.$accessToken,
	'Accept:application/vnd.yellowfin.api-v2+json',
	'Content-Type:application/json;charset=UTF-8'
);

//データソース定義読み込み
ob_start();
include("dataSource.json");
$datasource = ob_get_clean();

//データソース作成：BODYデータ作成
$ch3 = curl_init();
curl_setopt($ch3, CURLOPT_HTTPHEADER, $header3);
curl_setopt($ch3, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch3, CURLOPT_POSTFIELDS, $datasource);
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch3, CURLOPT_URL, $url3);
$result3 =curl_exec($ch3);
curl_close($ch3);
```

コンソールからプログラムを実行します。
```powershell:php 実行
PS> php addDatasource.php
```

データソースが追加されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/dca5cefa-d8aa-3361-1224-dc17fb51df8d.png)

## 最後に
REST API を呼び出して必要な処理を行うことができれば、どのようなプログラミング言語を選択しても処理することができます。Python や C# で処理を定義しても問題ありません。ただ、サーバーサイドで実行できるプログラムを選択することが重要です。JavaScript などで記述すると、サーバーサイドで実行するための一工夫が必要となります。
最後に、皆様、良いデータ分析を! See you then! Cheers!!