Salesforce Connectの設定 (WCF Data Services 4.5)

## Salesforce Connectとは

Salesforceから外部データに対してリアルタイムでアクセスできる機能。
データ自体をSalesforceに蓄えることなく外部オブジェクトとして操作することができる。

参考 : 
[Salesforce Connect の概要](https://trailhead.salesforce.com/ja/content/learn/modules/lightning_connect/lightning_connect_introduction)


## 環境
AWS上に以下の環境を構築。

- Webサーバ
    - WindowsServer 2008
    - IIS7.5

- DBサーバ
    - WindowsServer 2003
    - MS SQL Server 2005

## データベースの準備

### テーブル作成
Keyを設定した簡単なテーブルを用意。

### ユーザ作成
適当なユーザを作成。

参考 : 
[データベースのユーザーとデータベースへのログインユーザーの作成 (SQL Server Tips)](https://www.ipentec.com/document/sql-server-add-users)


## ログイン許可
- SQL Server を右クリック > プロパティ > セキュリティ > 認証をSQL Serverも含めるモードに設定
- ログインするユーザのデータベース接続権限を許可に設定

## Webサーバの準備

### IIS7.5 設定
「機能の追加」でIISを追加。
`regedit`を使い、今回使用するAMIに.NetFramework4.5がインストールされていることを確認する。

参考 :
https://docs.microsoft.com/ja-jp/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

### WCF HTTPアクティブ化
「機能の追加」で .Net Framework 3.5.1 > WCFアクティブ化 > HTTPアクティブ化 と 非HTTPアクティブ化 を追加。

IISの機能追加後アプリケーションプールのバージョンに`.Net Framework v4.0`を追加する。コマンドプロンプトで以下を実行する。


```
C:\Users\Administrator> cd C:\Windows\Microsoft.NET\Framework\v4.0.30319   

C:\Windows\Microsoft.NET\Framework\v4.0.30319> aspnet_regiis -i
```

参考 : 
[Enable the WCF HTTP Activation Feature in Windows Server 2008 R2](https://pubs.vmware.com/mirage-53/index.jsp?topic=%2Fcom.vmware.mirage.api.pg.doc%2FGUID-ACB8AD73-ED55-471A-AE43-4C1AB1F07FBF.html)


### アプリケーションプールの変更
アプリケーションプールが2.0になっているため、4.0に変更する。

IISマネージャー > サイト(Default Web Site等) を選択 > 右ペインの 詳細設定 > アプリケーションプール(統合) を選択して変更。

### ハンドラーマッピングの設定変更
以下ハンドラーの動詞に`PUT`と`DELETE`を追加する。

- ExtensionlessUrlHandler-Integrated-4.0
- ExtensionlessUrlHandler-ISAPI-4.0_32bit
- ExtensionlessUrlHandler-ISAPI-4.0_64bit

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235642/fdf5e930-e711-f0f0-e45b-bb64eff1c3fd.png)

### 認証の設定変更
IISの`認証`を確認すると`匿名認証`が有効になっており匿名ユーザIDが`IUSR`となっている。この箇所を`アプリケーション プールID`に設定。

## WCF Data Services の作成

以下のチュートリアルが大変参考になった。

[Creating WCF Data Service](http://www.wcftutorial.net/Creating-WCF-Data-Service.aspx)

Visual Studio 2015を使って作成した。
※2017はWCF Data Servicesのテンプレートを使用するために追加の対応が必要となる

[WCF data service template missing in VS2017](https://developercommunity.visualstudio.com/content/problem/25983/wcf-data-service-template-missing-in-vs2017.html)



### ADO.Net Entity Data Modelで気を付けるところ

Entity Framework 5.0 を選択しないとエラーになった。

[VerificationException with WCF Data Services](https://stackoverflow.com/questions/29809072/verificationexception-with-wcf-data-services)


変更箇所

```
    public class TestWcfDataService : DataService< /* TODO: put your data source class name here */ >
```

```
            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
```

変更後

```
//------------------------------------------------------------------------------
// <copyright file="WebDataService.svc.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;

namespace PetSuppliesService
{
    public class PetSuppliesData : DataService<YourEntities>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        }
    }
}

```

ビルドしてローカルに発行する。
出力されたすべてのファイルをIISにアップロードして .svc ファイルにアクセスできるか確認。

## Salesforceの設定

Trailheadの単元の通りに設定すれば問題なし。

[Salesforce Connect](https://trailhead.salesforce.com/ja/content/learn/modules/lightning_connect)


## 結果と残課題

外部データを外部オブジェクトとして認識できた。
~~また、外部オブジェクトの参照、作成、更新もできることを確認したが、削除が権限不足によりできなかった。
RESTの動きとして、`GET`と`POST`はできるが、`PUT`と`DELETE`ができない状態。
できない理由は`401 - Unauthorized: Access is denied due to invalid credentials.`。~~



## 余談
Visual StudioをローカルPCにインストールして作成を実施。
その際、ADO.NETクラス作成時に接続するDBはAWSのパブリックIPアドレスを指定し、DBとの通信ができることを確認した。
そのままAWS上のIISに発行したことで、IISからDBへの通信はパブリックIPアドレスをターゲットにした通信となるが、Security Groupにでは外部からの接続を許可していなかったため、DBとの通信が確率できずエラーとなっていた。
クラス作成後に.edmxファイルの中のDBのアドレスをPrivate IPに指定しなおしたところ接続できるようになった。