(CData)API Serverを使ってコードを書かずに外部のDBのデータをsalesforce側に連携する


# はじめに

一般的にシステム間連携というと、以下のようなパターンが考えられます。（どれを選択するかは要件次第）

- ファイル連携
- DB共有
- API連携
- メッセージング

この中で、salesforceと別システムを連携させようとする場合には、ファイル連携、API連携がよく使われるのではないかと思います。(自分観測範囲)

さらに、API連携もREST APIを使った連携方法や、"salesforce connect"というsalesforceに実装されている機能(有償のオプション機能)を使う方法など、幾つか用意されています。
今回はノンコーディングを目指すものとして、この"salesforce connect"を使ってみたいと思います。

salesforce connectとは、外部システムのデータの表示、検索、変更を可能とした機能で、外部システムのデータをsalesforce組織内にコピーすることなく、リアルタイムにアクセスすることができるようになります。

salesforce connectを使って、外部システムと接続するには以下いづれかのアダプタが必要となります。

- OData2.0 or OData4.0アダプタ
- 組織間アダプタ(別のsalesforce組織にREST APIを使って接続)
- カスタムアダプタ(Apex Connector Frameworkを使用して独自アダプタを開発)

今回はCData Softwareで提供している[API Server](https://www.cdata.com/jp/apiserver/)を使って、ODataサービスを用意し、外部にあるDBをsalesforce側に読み込むことを試してみました。
(大雑把にはこんな感じです)

![summary.png](https://qiita-image-store.s3.amazonaws.com/0/1840/51da96ea-805c-a4b5-fd06-d8251acf1792.png "summary.png")

 

# API Serverをherokuにデプロイする

以下、前提とします

- herokuアカウントを持っている
- API Serverの本体である ```apiserver.war```(17.0.6472.0) を入手済み

### 1.herokuデプロイコマンドの準備

herokuデプロイコマンドのプラグインをインストールしておきます（インストール済なら不要）

```bash
$ heroku plugins:install heroku-cli-deploy
```

### 2.heroku appの準備

herokuアプリを作成して、postgresをaddonします

```bash
$ heroku create trycdata
$ heroku addons:create heroku-postgresql:hobby-dev
```

また、環境変数として以下を追加します。addonしたDBのDatabase Credentialsを参照しながらセットしてください。

|key|value|
|:--|:--|
|APP_DB|(JDBCの接続文字列)|
|APP_USERS|(JDBCの接続文字列)|
|WEBAPP_RUNNER_OPTS|--tomcat-users-location ../../tomcat-users.xml|
|DATABASE_URL|(Provisioning時に自動でセットされる)|

#### DBへのSSL接続設定について

[SSL Required for all Standard and Premium tier Heroku Postgres databases from March 2018](https://devcenter.heroku.com/changelog-items/1363) にある通り、Standard/PremiumプランのDBへの接続にはSSL接続が必須となります。

API Serverから接続する場合には、```APP_DB```の値の末尾に以下のパラメータを追加すればSSL接続になる模様です。Standard or Premiumプランをお使いの場合には、ご注意ください。

```
ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory
```


### 3.Adminユーザの定義ファイル準備(tomcat-users.xml)

API Serverの管理者ユーザを定義しておきます(API Serverにログインするときに必要です)

```tomcat-users.xml
<?xml version='1.0' ?>
<tomcat-users>
  <user name="admin" password="admin" roles="cdata_admin" />
</tomcat-users>
```

### 4.herokuにwarファイルをデプロイ

herokuデプロイコマンドより、```apiserver.war```, ```tomcat-users.xml``` をデプロイします。

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

### 参考

* [WAR Deployment (heroku dev center)](https://devcenter.heroku.com/articles/war-deployment#deployment-with-the-heroku-cli)
* [Host the API Server on Heroku (CData)](https://www.cdata.com/kb/articles/odata-heroku.rst)


# API Server側の設定

「設定」タブよりAPI Serverを設定していきます

### 1.サーバーの設定

「信頼されたIPアドレス」にて、あらゆるIPアドレスからの接続を許可しておきます。
(IPアドレスのホワイトリストがあれば、それを参考にしてください)
「追加」からIPアドレス入力で「*」を登録します。

![apiserver_config_server.png](https://qiita-image-store.s3.amazonaws.com/0/1840/d823383c-8afb-7ab2-8a21-ae181a6f458a.png "apiserver_config_server.png")


### 2.接続の設定

API Serverから接続するDBを登録します。
「Add Connection」からheroku postgreへの接続を設定します。

![apiserver_config_dbconnection_01.png](https://qiita-image-store.s3.amazonaws.com/0/1840/1eff4e60-118a-89d8-8bce-fb760e55ef72.png "apiserver_config_dbconnection_01.png")

![apiserver_config_dbconnection_02.png](https://qiita-image-store.s3.amazonaws.com/0/1840/fed86cfd-e285-d0f1-5e79-3b1c8e068142.png "apiserver_config_dbconnection_02.png")

ここで、接続先のDBでSSL接続が必要ならば「Advanced」タブよりOhterパラメータとして、```ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory``` を追加しておきます。(例えば、HerokuのStandard/PremiumプランのDBを使う場合など)

![apiserver_config_dbconnection_03.png](https://qiita-image-store.s3.amazonaws.com/0/1840/d297a105-33db-bc52-6460-36350c7263ee.png "apiserver_config_dbconnection_03.png")

最後に「Test Connection」から正常に接続できることを確認しておきましょう。

### 3.リソースの追加

接続先のDBにて、公開するリソースを追加しておきます。
「リソースを追加」から接続先DB -> テーブル名 -> リソース名、操作可能なアクション、公開するカラム指定..
という具合にリソースを登録します。

### 4.接続ユーザの登録

API Serverに接続するユーザを定義しておきます。
「追加」からユーザ名、権限を指定してユーザを登録します。

![apiserver_config_user.png](https://qiita-image-store.s3.amazonaws.com/0/1840/28c4183a-d753-dba0-9068-86dc90de8130.png "apiserver_config_user.png")


登録すると、ユーザのAuthトークン情報も表示されます。(後で使います)

# Salesforceから繋げる

salesforceから、API Serverに接続するために「外部データソース」を定義します。

### 1.外部データソースの定義

設定画面のクイック検索で「外部データソース」と入力して外部データソースメニューを開きます。
新規外部データソースボタンからデータソースを追加します。
この登録画面の「認証」にて、API Server側で登録した接続ユーザ情報を指定します。

|項目|設定値|
|:--|:--|
|ID種別|指定ユーザ|
|認証プロトコル|パスワード認証|
|ユーザ名|(API Serverへの接続ユーザ名)|
|パスワード|(API Serverへの接続ユーザのAuthトークン)|

![sfdc_external_datasource.png](https://qiita-image-store.s3.amazonaws.com/0/1840/fdb48db8-52b3-e36c-c5a7-6d8ddeef02bb.png "sfdc_external_datasource.png")

### 2.外部オブジェクトの作成

外部データソースを登録した後、「検証して同期」ボタンよりsalesforce側からの接続を検証します。
検証に成功すると、API Server側で公開しているリソース(テーブル名)が表示されますので、同期したいテーブルを選択して「同期」ボタンで外部オブジェクトを作成します。

外部オブジェクトに対して、タブを作成するなどして、画面に表示させれば完了です！

![sfdc_external_objects.png](https://qiita-image-store.s3.amazonaws.com/0/1840/fc2584cb-5c34-4b7a-d7f9-70e4c23caa7f.png "sfdc_external_objects.png")


# さいごに

ここまで、ほぼコードを書くことなく外部システムとの連携を設定することができました。

設定作業は決して少ない量ではないと思いますが、この設定のみでSalesforceから外部オブジェクトとして外部のデータを参照することができるのは、なかなか良さげです。

ちなみに、heroku connectをプロビジョニングすればODataサービスも付いてくるので、それでも問題ないです。
ただ、API Serverを使うと、heroku以外のサーバに設置しているDBからもデータを取得できたり、salesforceから繋ぐ先を1箇所に集約できるので、複数のDBから連携するような場合には大きなメリットがあると思います。
※salesforce connectは、繋ぐ先ごとに有償(しかも結構お高い)ですので...


最後に今回の連携方式の活用シーンとしてはどんなものがあるでしょうか。
例えば、

* 現行システムからSalesforceに移行したいが、現行システムのデータをそのままSalesforceに移行できない(予算がない等で)ので、ひとまず現行システムのデータを参照できる仕組みを用意してSalesforceへの移行を促進させる
* データのバックアップ先として、外部のデータベースにデータを退避させる。ただ、過去データはいつでも参照したいので、外部オブジェクトとして参照できるようにする

というシーンで活用することも可能ではないかな、と思います。
設定だけで他システムとの連携を可能にする...という強力なツールということで、参考になれば幸いですw