[OutSystems]Integration BuilderでMongoDB Atlasにつないで見る

OutSystemsは、最近は外部システムとの接続にIntegration Builder (SaaSで外部システムとの接続用モジュールを生成するツール）を勧めている。
接続先も徐々に増えつつあり、そのなかにMongoDBもあった。設定を見ていると無料で使えるMongoDB Atlasとの接続もできそうなので試してみた。

なお、Integration Builderについては以前に書いた記事もある。
[Integration BuilderをSalesforce Developer Editionで試してみる](https://qiita.com/jyunji_watanabe/items/5a7992935ef21e0e7af7#outsystems%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%81%AB%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)
[Integration Builderで生成したモジュールの構成を確認する](https://qiita.com/jyunji_watanabe/items/d74ad927769c2db9df42)

# MongoDB Atlas側で準備
## MongoDB Atlasのアカウント等のセットアップ
Qiitaに良い記事があったのでこっちを参照（微妙に文言は変わっていたりするが特に問題は感じなかった）。
[MongoDB Atlasで無料かつ手軽にDB環境を利用してみる](https://qiita.com/n0bisuke/items/4d4a4599ee7ce9cf4fd9#1-%E6%8E%A5%E7%B6%9A%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E6%83%85%E5%A0%B1%E3%82%92%E4%BD%9C%E6%88%90)

## サンプルデータ
接続テストに使うので、サンプルデータセットを投入しておく（最初のセットアップ時にオプションがあった）。
データ容量が足りなくて（既にサンプルデータセットを投入済みなので）試せなかったが、Databaseメニューを開き、「...」→「Load Sample Dataset」選択でも投入できそう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/65246730-dc07-c9e8-a5f7-f92599e29a37.png)

## ネットワーク設定
MongoDB Atlasの設定で、許可するアクセス元IPアドレスを指定する機能がある。
指定しないとIntegration Builderでアクセスできないようだ。
今回はとりあえずMongoDB AtlasにIntegration Builderでつなぐとどうなるのか確認したいので、無制限アクセスにする。

1. サイドバーのメニューからNetwork Addressを選択
1. Add IP Addressボタンをクリック
1. ダイアログのALLOW ACCESS FROM ANYWHEREボタンをクリック (名前からして、文字通りどこからでもアクセスできる設定なので検証目的でのみ使う）
1. ダイアログ左下のスイッチ（This entry is temporary and will be deleted inのラベルがついているもの）をオンにしておく（危険な設定なので、検証が終わったら自動的に消えるように）
1. Confirmボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/ded12b38-7d87-5b9e-7b7f-e7eb26240a07.png)

### ちゃんと設定するなら
Integration Builderの[アーキテクチャの概要](https://success.outsystems.com/ja-jp/Documentation/11/Extensibility_and_Integration/Create_connectors_with_Integration_Builder/How_Integration_Builder_works#architecture)を見る限り、External System (今回はMongoDB Atlas) に対して、Integration BuilderとOutSystems環境双方からアクセスがあるように見える。しかし、実際にはIntegration BuilderからExternal SystemへのアクセスはOutSystems環境のService Center経由で行われるらしいので安心。

[Integrate with an external database using Integration Builder > Prerequisites](https://success.outsystems.com/Documentation/11/Extensibility_and_Integration/Integrate_with_an_External_Database/Integrate_with_an_external_database_using_Integration_Builder#prerequisites)によれば、

> All infrastructure servers must be able to connect to the external database.

なので、やはりPlatform ServerからMongoDBまでのパスが確保できていればよさそう。

念のため、Integration BuilderのIPは
[OutSystems network requirements > Network environment requirements > Integration Builder](https://success.outsystems.com/Documentation/11/Setup_and_maintain_your_OutSystems_infrastructure/Setting_Up_OutSystems/OutSystems_network_requirements#integration-builder)に記述がある。

OutSystems環境のIPは、オンプレミスならネットワーク担当に聞く。クラウドなら[Obtaining the front-ends' public IPs](https://success.outsystems.com/Support/Enterprise_Customers/Maintenance_and_Operations/Allowlist_your_OutSystems_cloud_environments_on_your_firewall#connecting-over-the-internet)かな。実際の設定する際にはサポートにも聞いたほうがいいかもしれない。

# Integration BuilderでMongoDB Atlasへの接続を作成してテスト
https://integrationbuilder.outsystems.com/IntegrationBuilder/
にアクセスする。

## MongoDB Atlasへの接続を作る
まず、Create Integrationボタンをクリックして開始。
Choose a providerでMongoDBを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/29e4ef55-9746-bd55-b860-4a57abdb16ae.png)

MongoDBへの接続情報を先に登録する必要があるので、画面右側の「Create a connection」ボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/f05080f8-3344-c9c3-d635-6a354952ba37.png)

接続情報を以下の通り設定。
1. Name: この接続につける（Integration Builder上での）名前
1. 接続には認証があるので、Authentication TypeはデフォルトのUsername and Passwordのまま
1. UsernameとPasswordは接続先のDatabaseに設定したUsername/Passwordを設定する
1. 接続先のHostnameは、MongoDB Atlas上で、サイドメニューのDatabase > 対象データベースのConnectボタン > Choose a connection methodで適当なものを選ぶと、接続文字列例が出るのでそこからコピーしたものを貼る（「自分でつけたDatabase名.サブドメイン.mongodb.net」のようになるようだ）。また、「Use DNS SRV to identify replica sets」のチェックボックスはMongoDB Atlas接続に必要な文字列をAdditional Optionsに設定してくれるのでオンにする
1. Databaseを設定する。サイドメニューのDatabase > 対象データベースのBrowse CollectionsボタンをクリックするとDatabaseの一覧が見える（ここでは、サンプルデータのsample_restaurantsを設定）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/bc7bdd94-2879-dda1-afd7-4801627c20fb.png)

Browse Collectionsの表示例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/4b91e10a-0e66-ab18-f36f-6bfbdcfe3224.png)

## Integrationのモジュールを作る
Connectionを作成すると、Integration作成画面に戻る。
今作成したConnectionを選択し、右下のNextボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/9cfb5df8-745a-dcec-f080-70a7e202be1d.png)

Connection作成時に指定したDatabase内のCollectionが左側に列挙される。
Integrationに含めたいCollectionを選択すると右に属性の一覧が表示される。属性も含めたいものだけ選択するようだが、テストなのでそのまま選択可能なものは含めておく。
最後にまた、画面右下のNextボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/2a05e612-e27b-bc6d-d9cd-9411965d4622.png)

Review画面で設定を確認して問題なければ、画面右下のPublishボタンをクリック。
Integration Builderで作るモジュールはIntegrationパターンに則ったものができるので、Consumerモジュールから参照するのは名前の末尾に_ISがついている方のモジュール。_DRVがついているのはMongoDBとISモジュールの間に入り、MongoDBと直接遣り取りをするためのもの。
（モジュール名末尾に「_1」がついているのは、このスクリーンショットを取る前に、動作確認のために別のIntegrationを作っていたため）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/fe9351ba-f0da-61fe-3d06-fb6367de04ea.png)

## テストアプリケーションで動作確認
ここではSearchのActionを使って動作確認してみる。

### ISモジュールを参照
Service Studioで出来上がったモジュールへの参照を追加する。
以下の通り、Collectiopn毎にCRUD・Count・Searchの操作に対応するActionができている。
テストなので全部参照追加しておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/33cdb030-28c0-30f6-d0e1-ce49257aad3f.png)

### 動作確認
結果をListで返してくれるSearch**のActionを使ってどんな値が返ってくるのか確認。
画面とそのData Actionを作り、Data Action内で以下の通り、検索条件等を指定せず、Max Record=1だけ設定（戻ってくる値の形だけみたいので）し、結果を画面に表示してみる。

restaurants Collectionに対するSearch Actionの方を使ってみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/06ed7c84-6fe3-1e8f-0569-2deb21114096.png)

これが出力結果（SearchRestaurantsDocuments.Results.Currentをそのまま表示）。
ResultsプロパティがText List型であることからも分かる通り、結果はJSON形式。このままではプログラムから使いにくい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/bef892ba-af7f-05ae-294f-d6f7b8449ea0.png)

### 結果を解釈するためのStructureを準備する
ドキュメントにこの部分の対応手順が書いてある（Integration Builderで自動生成すべきな気がするが。また、Integration BuilderでIntegrationを作るときのオプションに自動生成してくれそうなものがあり、選んでいるのだが作ってくれていない）。

[Fetch a list of records from a collection with JSON Format](https://success.outsystems.com/Documentation/11/Extensibility_and_Integration/Integrate_with_an_External_Database/Integrate_with_an_external_database_using_Integration_Builder/Using_MongoDB_integration#fetch-a-list-of-records-from-a-collection-with-json-format)にある手順に従って作業してみる。

1. ↑の動作確認で出力結果に表示されたJSONをコピー
1. Service StudioでDataタブ > Structuresを右クリック > Add Structure from JSON...を選択
1. Add Structure From JSONダイアログで名前をRestaurant、本文をコピーしたJSONに設定し、Add Structureボタンをクリック→これでRestaurantという名前でJSONの構造に対応するStructureが作成される
1. Search Actionの戻り値をRestaurant Listに変換する（下のAction Flow参照。SearchがText Listで返すため、For Eachでループし、個別のTextをJSONDeserializeでRestaurant型に変換。変換後の値をList Appendで、Data ActionのOutput Parameterに追加している。なおData ActionのOutput ParameterはRestaurant List型に変更）
1. Data ActionのOutput Parameterを画面にドラッグ＆ドロップして一覧表を作ってテスト

Add Structure From JSONダイアログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/9c759f60-1a96-f647-8277-a70b52e46708.png)

変更後のAction Flow（Search ActionのMax Recordパラメータは適当に20くらいに増やす）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/fd4193df-861a-0dc8-ba2c-c485391369d6.png)

表示例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/aa591739-7914-0812-2d9b-e10873c1b588.png)