Azure対応のカスタムプラグインを作成し、Two-Way用のサービスコントラクト(ITwoWayServiceEndpointPlugin)を実装したAzure AppFabric ServiceBus リスナーにプラグインのメッセージをポストする一連の手順を記載します。サービスバスにポストされたメッセージを処理する AppFabric サービスバスリスナーアプリケーションの作成は、 [Dynamics CRM 2011]Azure対応(Azure Aware)カスタムプラグインを作成する その2で行います。Azure 対応のカスタムプラグインやワークフローアクティビティーの作成方法について参考となるURLを掲載します。というか今回サンプルほぼそのまんまですが。

Azure 対応のカスタム プラグインの記述
http://msdn.microsoft.com/ja-jp/library/gg328194.aspx
サンプル: Azure 対応のカスタム プラグイン
http://msdn.microsoft.com/ja-jp/library/gg328226.aspx
サンプル: Azure 対応のユーザー定義ワークフロー活動
http://msdn.microsoft.com/ja-jp/library/gg327854.aspx 

カスタムプラグインをわざわざ作成しなくても、[Dynamics CRM 2011]Dynamics CRM 2011と連携する AppFabric サービスバス リスナーアプリケーションを作るその1 で記載したステップの登録手順に従って、標準で用意されている ServiceBusPlugin を使用すれば、サービスバスとの連携は行うことができます。カスタムプラグインを作成すると、Two-WayやREST リスナーのExecuteメソッドの返り値(文字列)を取得して何らかの処理を実装できるようになります。

動作環境は次の通りです

  • Dynamics CRM 2011 Online
  • Visual Studio 2010 Professional で開発
  • Windows Azure AppFabric SDK V1.5 を使用

前提として、Windows Azure 上で AppFabric サービスバスの設定は行っていることとします。本サンプルでは、[Dynamics CRM 2011]Dynamics CRM 2011と連携する AppFabric サービスバス リスナーアプリケーションを作るその1 で登録したサービスバス(名前空間:Netplanetes-Crm-Sample) を使用することとします。

1. Azure対応カスタムプラグインを作成

Visual Studio 2010を起動して、クラスライブラリプロジェクトを作成します。本例では AzureAwareCustomPlugin という名前で作成しています。新しいプロジェクトの追加ダイアログでOKボタンをクリックします。

クラスライブラリプロジェクトが作成された後、参照の追加を行います。下図のように参照の追加画面の参照タブで、microsoft.crm.sdk.proxy.dll と microsoft.xrm.sdk.dll を選択して OK ボタンをクリックします。dllはDynamics CRM SDK の binフォルダに配置されています。

同様の手順で 下図のように System.Runtime.Serialization を参照先として追加します。

参照設定が終わったので、クラスライブラリ作成時に自動で生成された Class1.cs を削除します。

ソリューションエクスプローラ上のプロジェクトを右クリック→追加→新しい項目 を選択します。新しい項目の追加ダイアログが表示されます。テンプレートにクラスを選択して、AzureAwareCustomPluginSample01という名前でクラスファイルを作成します。

作成したクラスファイルを次のように編集します。プラグインでは、コンストラクタの引数に、この後作成するサービスエンドポイントのID(GUID)を指定することを前提となっています。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;

namespace AzureAwareCustomPlugin
{
    /// <summary>
    /// プラグインに渡された実行コンテキストをAzure AppFabric サービスバスにポストするプラグイン.
    /// コンストラクタで、サービスエンドポイントのGUIDを渡される必要があります。
    /// </summary>
    public class AzureAwareCustomPluginSample01 : IPlugin
    {
        private Guid serviceEndpointId;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="unsecure">サービスエンドポイントのID</param>
        public AzureAwareCustomPluginSample01(string unsecure)
        {
            if (string.IsNullOrEmpty(unsecure) || !Guid.TryParse(unsecure, out serviceEndpointId))
            {
                throw new InvalidPluginExecutionException("サービスエンドポイントのIDがコンストラクタの引数に指定されていません");
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        public void Execute(IServiceProvider serviceProvider)
        {
            // IPluginExecutionContext を取得   
            // プラグインの実行コンテキスト情報を取得します。   
            IPluginExecutionContext context = serviceProvider.GetService(typeof(IPluginExecutionContext)) as IPluginExecutionContext;
            // IOrganizationServiceFactory を取得します   
            // IOrganizationServiceを作成するのに使用します   
            IOrganizationServiceFactory factory = serviceProvider.GetService(typeof(IOrganizationServiceFactory)) as IOrganizationServiceFactory;
            // ITracingService を取得   
            // トレース情報を出力するために使用します。   
            ITracingService trace = serviceProvider.GetService(typeof(ITracingService)) as ITracingService;
            // IServiceEndpointNotificationService を取得
            // Azure AppFabric ServiceBus に実行コンテキストをポストするために使用します。
            IServiceEndpointNotificationService cloudService = serviceProvider.GetService(typeof(IServiceEndpointNotificationService)) as IServiceEndpointNotificationService;
            if (cloudService == null)
            {
                throw new InvalidPluginExecutionException("IServiceEndpointNotificationService の取得に失敗しました");
            }

            try
            {
                trace.Trace("実行コンテキストをポストします。");
                string response = cloudService.Execute(new EntityReference("serviceendpoint", serviceEndpointId), context);
                if (!string.IsNullOrEmpty(response))
                {
                    trace.Trace("Response:{0}", response);
                }
            }
            catch (Exception ex)
            {
                trace.Trace("例外が発生しました:{0}\n{1}", ex.Message, ex.ToString());
                throw;
            }
        }
    }
}

プラグイン内のソースでは、Executeメソッドの返り値として文字列を受け取っています。サービスエンドポイントのコントラクトが Two-Way や REST の場合は、文字列を返り値として受け取れるので、なんらかの処理を行えます。

プラグインは署名されている必要があります。ソリューションファイル上のプロジェクトを右クリック→プロパティを選択します。プロパティ画面の署名タブで、下図のようにアセンブリの署名をチェックし、既存のキーファイルかキーファイルを新規作成します。

以上でプラグインの作成は完了です。以降では、PluginRegistrationTool を使用して アセンブリの登録とサービスエンドポイントの作成をします。

2.ServiceEndpoint の作成とステップの登録

PluginRegistrationTool を起動して、 Dynamics CRM に接続します。本例では CRM Online に接続しています。下図のように組織のプラグイン登録情報を表示し、タブのメニューのRegister→ Register New Assembly をクリックします。

Register New Plugin 画面が表示されるので、作成したプラグインを指定します。Azure 対応のプラグインは Sandbox で動作する必要があるため、Step #3 では Sandbox を選択します。アセンブリの保存場所は Database を指定します。Register Selected ボタンをクリックします。

登録に成功すると、下図のようにアセンブリとプラグインが表示されるようになります。

次のサービスエンドポイントを作成します。Azure AppFabric サービスバス自身は、で作成したサービスバスを使用します。以降の設定手順は [Dynamics CRM 2011]Dynamics CRM 2011と連携する AppFabric サービスバス リスナーアプリケーションを作るその1の"3. サービスエンドポイントとプラグインステップの設定" とほぼ同じ手順となります。不明点があればそちらも参照してください。

プラグインレジストレーションツールの同じ画面で、Register → Register New Service Endpoint をクリックします。

Service Endpoint Details 画面が表示されます。Name に今回作成する Service Endpoint の名前を指定します。Description にエンドポイントの説明を記述します。Solution Namespace はAppFabric Service Busで作成したサービスバスの名前空間を指定します。Pathはエンドポイントアドレスのパスを指定します。Contract は今回は TwoWay を指定します。そのほかは既定値のままとします。

Save & Configure ACS ボタンをクリックします。

ACS Configuration 画面が表示されます。Management Key には、作成済みのWindows Azure AppFabric サービスバス画面の右側プロパティの下に表示される、既定のキーの表示ボタンで表示される既定のキーを入力します。 Certificate File はCRM Online の開発者リソースのページでダウンロードした証明書ファイルのパスを設定します。Issuer Name は証明書の発行者名を指定します。CRM Onlineの場合は証明書のダウンロードリンクの上部に記載されていた名前です。CRM Onlineの組織をアジアで作成した場合は、 crm5.dynamics.com になります。

OnPremiseやIFD構成の場合のキー関連の設定は次のURLを参照
- チュートリアル: Windows Azure との統合用の CRM の構成
http://msdn.microsoft.com/ja-jp/library/gg328249.aspx

署名情報の入力が完了したら、 Configure ACS ボタンをクリックします。エラーが発生しないことを確認して、Closeボタンをクリックします。

Service Endpoint Details 画面に戻ります。サービスエンドポイントの作成に成功すると 下図赤枠のIDにサービスポイントのIDが表示されます。このIDはカスタムプラグインのステップ登録時にコンストラクタの引数として指定する文字列となります。Save & Veryfy ボタンをクリックします。

Verify Authentication 画面が表示されます。エラーが発生しないことを確認して、 Close ボタンをクリックします。 Service Endpoint Details ダイアログの Save ボタンをクリックして画面を閉じます。

プラグインレジストレーションツールで、下図のようにサービスエンドポイントが登録らされていることを確認します。カスタムプラグインからサービスバスに対してメッセージをポストするので、ステップの登録はカスタムプラグインに対して行います。標準のServiceEndpointプラグインに対して行わないので注意してください。作成した AzureAwareCustomPluginSample01 を右クリック→Register New Step をクリックします。

Register New Step 画面が表示されます。今回は取引先企業作成時に、プラグインが起動されるようにします。MessageにCreate, Primary Entity に account を入力します。ステージを Post-Operation , 実行モードをAsynchronous, Deployment を Server に設定します。赤枠のよういん、Unsecure Configuration に作成したサービスエンドポイントのGUIDを設定します。 入力内容を確認して、Register New Step ボタンをクリックします。

以上で準備は完了です。

3.まとめ

今回の説明は以上です。AppFabric サービスバスリスナーアプリケーションを作成して、動作させていません。そのため、このまま取引先企業を作成して非同期プラグインが動作すると、システムジョブに失敗としてレコードが作成されてしまいます。Two-Wayコントラクト用の ITwoWayServiceEndpointPlugin を実装した Azure AppFabric リスナーアプリケーションは [Dynamics CRM 2011]Azure対応(Azure Aware)カスタムプラグインを作成する その2作成します。