(Heroku上で)API Server + Exchange JDBC Driver で、Exchangeのデータ取得をAPI化する


## 概要

* CDataが提供するAPI Serverに、Exchange JDBC Driverを組み込むことができます。
* API Serverを経由して、Exchange内のデータを取得することができます。
    * ユーザをパラメータとして指定してクエリすることができます。
* （ついでに）Salesforceが提供するLightning Syncだと定期的な予定を取得することはできないですが、この方法だと定期的な予定も取得可能です。

## Herokuへのデプロイまで

(CData API Serverのデプロイなどについては[こちらの記事](https://qiita.com/yonet77/items/38810f91f0fb72369dc7)を参照ください)

API ServerにExchange JDBC Driverを追加して、Herokuにデプロイしてみます。
以下、手順の概要です。

1. Exchange JDBC Driverを [ダウンロード](http://www.cdata.com/jp/drivers/exchange/download/jdbc/) します
    * zipを解凍して、setup.jarからローカルにインストールします(ライセンスは評価版で)
2. ```apiserver.war``` を展開します
3. Exchange JDBC Driverインストール先の/lib配下の以下のファイルを、API Serverを展開した先の ```/WEB-INF/lib``` 配下にコピーします
    * ```cdata.jdbc.exchange.jar```
    * ```cdata.jdbc.exchange.lic```
4. warファイルを生成します(API Serverを展開したディレクトリにて実施)

    ```bash
    $ jar cf ../apiserver.war ./
    ```
    
5. ```tomcat-users.xml``` を用意します
    * API ServerにログインするときのID/PWを定義したものです
    * ```apiserver.war``` と同じディレクトリにおいておきます(後述する環境変数:```WEBAPP_RUNNER_OPTS```と連動するように)
6. heroku appにpostgresqlを追加して、環境変数を設定します

    ```bash
    $ heroku addons:create heroku-postgresql:hobby-dev --app (アプリ名) --version 9.6
    ```
    * なお、version指定はたまたまです

    |環境変数名|値|
    |:--|:--|
    |APP_DB|(JDBC接続文字列)|
    |APP_USERS|(APP_DBと同じ値)|
    |WEBAPP_RUNNER_OPTS|```--tomcat-users-location ../../tomcat-users.xml```|
    
    
    * SSL接続が必須であればJDBC接続文字列の末尾に以下を追加します。
        
        ```?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory```

7. herokuにデプロイします

    ```bash
    $ heroku war:deploy ./apiserver.war --includes ./tomcat-users.xml --app (アプリ名)
    ```


### API Server側の接続設定

API Serverにログインした後、「設定」->「接続」で、Add Connectionボタンより追加する接続先の種類を選択する画面で、"Others"に"Exchange"が追加されているので、それを指定します。

![apiserver_add_connection.png](https://qiita-image-store.s3.amazonaws.com/0/1840/ef3a90ca-7708-d08c-27f1-8663854d3f2c.png "apiserver_add_connection.png")

Exchange Serverへの接続情報を設定して、Test Connectionボタンより接続テストします。

![apiserver_setting_exchange.png](https://qiita-image-store.s3.amazonaws.com/0/1840/0c9e0516-41ed-5608-02f4-025e11dba25e.png "apiserver_setting_exchange.png")

#### (ちょっと横道)Exchange側でIP制限している場合

Herokuから外部へのリクエストでIPアドレスを固定化したい場合、2種類の方法があります。
[参考](https://qiita.com/sho7650/items/872b5757e250d4b3eb95)

今回は```Proximo```を使うことにします。

```bash
$ heroku addons:create proximo:development --app (アプリ名)
```

で、Proximoを追加します。

Exchange Serverとの接続設定にて、「Advanced」タブにあるProxy関連の設定に追加したProximoの情報をセットします。

![apiserver_setting_exchange_proxy.png](https://qiita-image-store.s3.amazonaws.com/0/1840/f18ed87d-0a23-c926-5583-b122dd9ad1fb.png "apiserver_setting_exchange_proxy.png")

Herokuの環境変数 ```PROXIMO_URL``` に接続情報があるので、それを元に値をセットします。

```PROXIMO_URL``` : ```http://(0):(1)@(2)```

|項目|値|備考|
|:--|:--|:--|
|ProxyAuthScheme|BASIC|※デフォルトのまま|
|ProxyAutoDetect|False|Falseに変える|
|ProxyPassword|(1)||
|ProxyPort|80|※デフォルトのまま|
|ProxySSLType|AUTO|※デフォルトのまま|
|ProxyServer|(2)||
|ProxyUser|(0)||


## Exchangeのデータを取得

Exchangeへの接続テストが成功したら、Exchangeへのリソースを追加して、API Serverを経由してExchangeのデータを取得してみたいと思います。

### 偽装ユーザ名を使ったクエリ

ユーザを固定してAPIを用意するとなると、ユーザの数だけAPIを用意することとなって、非常に手間がかかりますので、ユーザを指定してクエリできるようにすることがほぼ必須と言えるでしょう。

1. 接続設定
    * Exchange Serverへの接続設定にて、以下のように設定
        * ImpersonationUser -> (ブランク)
        * ImpersonationType -> PrincipalSmtpAddress(自分が設定したときは)
        * PsudoColumns -> Calendar=*
2. リソース設定
    * リソースのカラム一覧を見ると「ImpersonationUser」が利用可能になるので、チェックを入れて保存
    * RSD定義で、以下を追加(追加しないと動かなかった...)

    ```
    <!-- 処理定義 -->
    <rsb:script method="GET">
      <rsb:push op="apiSelect" />
    </rsb:script>
    ```

### クエリしてみる

API ServerのFilter条件に、```ImpersonationUser```を追加してクエリすると、そのユーザでカレンダ情報を取得できました。

![cdata_apiserver_w_exchangedriver.png](https://qiita-image-store.s3.amazonaws.com/0/1840/f6e4cb73-8780-5507-9fc7-0c15f17919d5.png "cdata_apiserver_w_exchangedriver.png")


`Calendar`の他には、`Contacts`, `Drafts`, `Folders`, `Inbox`, `Outbox`, `Tasks` などもクエリできる模様です。詳細は、[製品ページ](https://www.cdata.com/jp/drivers/exchange/jdbc/)あるいは、製品をダウンロードしてヘルプを参照すると良いでしょう。

## さいごに

API Serverに他のJDBC Driverを組み込むことで接続先を拡張することが可能です。
今回は、Exchange JDBC Driverを試しましたが、API Serverに備わってない別のDriverも試せるのではないかと思います。

他システムとの連携において、APIは必須でありますが、ゼロから作り込んでいくのはなかなか時間がかかると思います。(APIを用意した後も色々と作り込んでいくものがあると思います。)
今回のようにCData Softwareが提供する製品をうまく組み合わせることで、API作成の工数を大幅に低減できることでしょう。

### (ちなみに)

Salesforceが提供しているLightning Sync for Microsoft Exchangeでは、定期的な行動を取得できない(Spring '18時点)ので、定期的な行動を取得する場合には、この方法も選択肢の1つとして検討しても良いかと思います。