Azure 対応のカスタム プラグインの記述

Azure を操作するプラグインの記述は、他の Dataverse プラグインの記述と似ています。 ただし、目的の Web サービス メソッドの呼び出しに加えて、プラグインには、現在のトランザクションの実行コンテキストの Azure Service Bus へのポストを開始するコードを含める必要があります。

プラグインの設計に関する考慮事項

同期的に実行されるプラグインの場合、リスナー アプリケーションまたはその他の外部サービスから情報を取得するために、プラグインがAzureにメッセージを送信するように設計することをお勧めします。 データ文字列をプラグインに返すことができる Azure Service Bus エンドポイントでの二方向または REST 契約を使用します。

同期プラグインがAzure Service Busを使用して外部サービスでデータを更新することはお勧めしません。 外部サービスが利用できなくなったり、更新するデータが大量にある場合は、問題が発生する可能性があります。 同期プラグインは、高速実行し、長時間の操作を実行する間はログインしている組織のすべてのユーザーを保持しないようにします。 また、プラグインが起動する現在のコア操作のロールバックが発生すると、プラグインで行われたデータの変更は取り消されます。 このロールバックにより、 Dataverse 外部サービスが同期されていない状態になる可能性があります。

同期登録プラグインは、現在のトランザクションの実行コンテキストをAzure Service Busに投稿することができます。

プラグインのコードを記述する

次のサンプル プラグインでは、Azureサービス プロバイダーを取得し、呼び出しによって実行コンテキストをService Busに投稿するコードが追加されています Execute(EntityReference, IExecutionContext)。 プラグインはサンドボックスで実行する必要があるため、プラグインのデバッグを容易にするトレース コードが追加されています。

注意

このコードでコンストラクターに渡された serviceEndpointId は、チュートリアル: Dataverse との統合のための Azure (SAS) の構成で説明されたサービス エンドポイントの作成から取得したものです

ユーザーのブラウザーと [organization Uri]/api/data/v9.0/serviceendpoints?$select=name,description,serviceendpointid のようなクエリを使用する Web API に対して GET 要求を使用することにより、ユーザーの環境で使用可能なサービス エンドポイントをクエリすることができます。

using System;
using System.Diagnostics;
using System.Threading;
using System.Runtime.Serialization;

using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

using Microsoft.Xrm.Sdk;

namespace Microsoft.Crm.Sdk.Samples
{
    /// <summary>
    /// A custom plug-in that can post the execution context of the current message to the Windows
    /// Azure Service Bus. The plug-in also demonstrates tracing which assist with
    /// debugging for plug-ins that are registered in the sandbox.
    /// </summary>
    /// <remarks>This sample requires that a service endpoint be created first, and its ID passed
    /// to the plug-in constructor through the unsecure configuration parameter when the plug-in
    /// step is registered.</remarks>
    public sealed class SandboxPlugin : IPlugin
    {
        private Guid serviceEndpointId; 

        /// <summary>
        /// Constructor.
        /// </summary>
        public SandboxPlugin(string config)
        {
            if (String.IsNullOrEmpty(config) || !Guid.TryParse(config, out serviceEndpointId))
            {
                throw new InvalidPluginExecutionException("Service endpoint ID should be passed as config.");
            }
        }

        public void Execute(IServiceProvider serviceProvider)
        {
            // Retrieve the execution context.
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            // Extract the tracing service.
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            if (tracingService == null)
                throw new InvalidPluginExecutionException("Failed to retrieve the tracing service.");

            IServiceEndpointNotificationService cloudService = (IServiceEndpointNotificationService)serviceProvider.GetService(typeof(IServiceEndpointNotificationService));
            if (cloudService == null)
                throw new InvalidPluginExecutionException("Failed to retrieve the service bus service.");

            try
            {
                tracingService.Trace("Posting the execution context.");
                string response = cloudService.Execute(new EntityReference("serviceendpoint", serviceEndpointId), context);
                if (!String.IsNullOrEmpty(response))
                {
                    tracingService.Trace("Response = {0}", response);
                }
                tracingService.Trace("Done.");
            }
            catch (Exception e)
            {
                tracingService.Trace("Exception: {0}", e.ToString());
                throw;
            }
        }
    }
}

プラグイン コードで、ポストを開始する前にコンテキストで書き込み可能データを更新できます。 たとえば、コンテキスト内の共有変数にキー/値のペアを追加できます。

プラグイン登録

Azure対応のカスタム プラグインを登録する場合、いくつかの制限があります。 プラグインは、サンドボックスで実行するよう登録する必要があります。 サンドボックス登録により、プラグインはメソッド、Azureソリューション メソッドの呼び出し、またはWebクライアントを使用したネットワークへのアクセスに制限されます。 IOrganizationService ローカル ファイル システムへのアクセスなど、他の外部アクセスは許可されません。

非同期モードで実行するように登録されたプラグインの場合、他の非同期プラグインと比較したプラグインの実行順序は保証されません。 さらに、非同期プラグインは常にコア操作の後に実行されます。 Dataverse

Service Bus ポストの失敗の処理

失敗した Service Bus 送信での所定の動作は、プラグインが同期実行と非同期実行のどちらで登録されているかによって異なります。 非同期プラグインでは、実際に実行コンテキストをサービス バスに投稿するシステム ジョブが投稿を再試行します。 同期に登録されたプラグインの場合、例外が返されます。 詳細 ランタイム エラーの管理と通知

重要

非同期として登録されたプラグインの場合のみ、Azure Service Bus に投稿された非同期ジョブが投稿失敗後に再試行されると、プラグイン ロジック全体が再び実行されます。 このため、コンテキストの変更と Service Bus への投稿以外に、ユーザー定義の Azure 対応プラグインにほかのロジックを追加しないでください。

非同期に実行するように登録されたプラグインの場合、Service Bus 経由で送信されたメッセージの本文に含まれる RemoteExecutionContextOperationId のプロパティと OperationCreatedOn プロパティを含みます。 これらのプロパティは、関連するシステム ジョブ (AsyncOperation) の AsyncOperationIdCreatedOn 列が作成したデータと同じデータが含まれます。 Azure Service Bus ポストを再試行する必要がある場合、このような追加のプロパティにより順序付けと重複データ検出が容易に行われます。

参照

Azure 統合
Azureソリューションでデータを操作する Microsoft Dataverse
サンプル: Azure 対応のカスタム プラグイン
プラグインを記述する
イベント実行パイプライン
プラグインの登録および展開

注意

ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)

この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。