次の方法で共有


Visual Studio Code を使用して Azure Logic Apps Rules Engine プロジェクトを作成する (プレビュー)

適用対象: Azure Logic Apps (Standard)

重要

この機能はプレビュー段階にあり、「Microsoft Azure プレビューの追加使用条件」が適用されます。

ビジネス ロジックを Azure Logic Apps の Standard ワークフローと統合する場合は、Visual Studio Code を使用して Azure Logic Apps Rules Engine プロジェクトを作成してビルドできます。 ルールは、ビジネス プロセスのしくみに関するビジネス ロジックを管理します。

この攻略ガイドでは、Azure Logic Apps Rules Engine プロジェクトを作成する方法について説明します。

  • Microsoft Rules Composer を使用してプロジェクトのビジネス ルールを作成するなど、Azure Logic Apps Rules Engine プロジェクトを作成するための前提条件とセットアップ。

  • 既存のルールがある場合は、Microsoft BizTalk Server からエクスポートします。

  • Visual Studio Code を使用して、Azure Logic Apps Rules Engine 用の Standard ロジック アプリ プロジェクトを作成します。

前提条件

プロジェクトを作成する前に

ルール エンジン プロジェクトを確実に成功させるには、次の一般的なタスクとベスト プラクティスを確認して実行します。

  1. ビジネス ルールがビジネス プロセスにどのように適合するかを決定します。

  2. アプリケーションにビジネス ルールを組み込む方法を検討します。

  3. アプリケーション内で、ルールによって表すビジネス ロジックを特定します。

    "ビジネス ロジック" という用語は、多くのことを指すことができます。 たとえば、"500 ドルを超える発注書にはマネージャーの承認が必要です" というビジネス ロジックが考えられます。

  4. ルール要素のデータ ソースを特定します。 オプションで、ボキャブラリ (基になるバインドを表すドメイン固有の命名規則) を定義できます。

  5. ボキャブラリ定義から、またはデータ バインディングから直接使用するルールを定義します。 これらのルールから、ビジネス ロジックを表すルールセットを作成します。

Microsoft BizTalk Server からルールをエクスポートする

Microsoft BizTalk Server から既存のルールを再利用するには、それらをエクスポートします。 ただし、現在、DB ファクトはサポートされていません。 ルールをエクスポートする前に、Microsoft BizTalk Rules Composer を使用して、ルールを削除するか、他の種類のファクトにリファクタリングします。

  1. Microsoft BizTalk Server から、ビジネス ルール エンジン展開ウィザードを起動します。

  2. [ルール エンジン展開ウィザードへようこそ] ページで、[次へ] を選択します。

  3. [展開タスク] ページで、[ポリシー/ボキャブラリをデータベースからファイルにエクスポートする] を選択し、[次へ] をクリックします。

  4. [ポリシー ストア] ページの [SQL Server 名] 一覧で、SQL Server を選択します。 選択したサーバーの構成データベースの一覧で BizTalkRuleEngineDb を選択し、[次へ] を選択します。

  5. [ポリシー/ボキャブラリのエクスポート] ページの [ポリシー] 一覧から、目的のポリシーを選択します。 定義ファイルを検索して選択するには、[参照する] を選択します。

  6. 準備ができたら、 [次へ] を選択します。

  7. サーバー、データベース、ポリシーまたはボキャブラリの情報を確認し、[次へ] を選択します。

  8. インポートまたはエクスポートが完了したら、[次へ] を選択します。

  9. インポートまたはエクスポートの完了状態を確認し、[完了] を選択します。

Azure Logic Apps Rules Engine プロジェクトを作成する

  1. Visual Studio Code のアクティビティ バーで、Azure アイコンを選択します。 (キーボード: Shift + Alt + A)

  2. 開いたAzure ウィンドウの [ワークスペース] セクション ツール バーで、[Azure Logic Apps] メニューから、[新しいプロジェクトの作成] を選択します。

    スクリーンショットは、Visual Studio Code、Azure ウィンドウ、選択したオプションである [新しいロジック アプリ ワークスペースの作成] を示しています。

  3. 「フォルダー選択」 ボックスで、プロジェクト用に作成したローカル フォルダーを見つけて選択します。

  4. 「新しいロジック アプリ ワークスペースを作成する」 プロンプト ボックスが表示されたら、ワークスペースに付ける名前を入力します:

    ワークスペース名の入力を求めるプロンプトが表示された Visual Studio Code を示すスクリーンショット。

    この例では MyLogicAppRulesWorkspace とします。

  5. [ロジック アプリ ワークスペースのプロジェクト テンプレートを選択してください] プロンプト ボックスが表示されたら、[ルール エンジン プロジェクトを使用するロジック アプリ (プレビュー)] を選択します。

    ロジック アプリ ワークスペースのプロジェクト テンプレートを選択するダイアログが表示された Visual Studio Code を示すスクリーンショット。

  6. 後続のプロンプトに従って、次の例の値を指定します:

    項目 値の例
    関数プロジェクトの関数名 RulesFunction
    関数プロジェクトの名前空間名 Contoso.Enterprise
    ワークフロー テンプレート:
    - ステートフル ワークフロー
    - ステートレス ワークフロー
    ステートフル ワークフロー
    ワークフロー名 MyRulesWorkflow
  7. [Open in current window] (現在のウィンドウで開く) を選択します。

    この手順を完了すると、Visual Studio Code でワークスペースが作成されます。例として、既定では、関数プロジェクトとロジック アプリ ルールのエンジン プロジェクトが含まれます。

    スクリーンショットは、Visual Studio Code と作成されたワークスペースを示しています。

    Node 説明
    <ワークスペース名> 関数プロジェクトとロジック アプリ ワークフロー プロジェクトの両方が含まれます。
    関数 関数プロジェクトの成果物が含まれます。 たとえば、<関数名>.cs ファイルは、コードを作成できるコード ファイルです。
    ロジック アプリ ワークフローを含む、ロジック アプリ ルールのエンジン プロジェクトの成果物が含まれます。

ルール エンジン コードを記述する

  1. ワークスペースで、[関数] ノードを展開します (まだ展開されていない場合)。

  2. この例では、RulesFunction.cs という名前の <関数名>.cs ファイルを開きます。

    既定では、このファイルには、次のコード要素を含むサンプル コードと、前に指定した値の例が必要に応じて含まれています。

    • 名前空間名
    • クラス名
    • 関数名
    • 関数のパラメーター
    • の戻り値の型 :
    • 複合型

    次の例は、RulesFunction という名前の関数の完全なサンプル コードを示しています。

    //------------------------------------------------------------
    // Copyright (c) Microsoft Corporation. All rights reserved.
    //------------------------------------------------------------
    
    namespace Contoso.Enterprise
    {
        using System;
        using System.Collections.Generic;
        using System.Threading.Tasks;
        using Microsoft.Azure.Functions.Extensions.Workflows;
        using Microsoft.Azure.WebJobs;
        using Microsoft.Azure.Workflows.RuleEngine;
        using Microsoft.Extensions.Logging;
        using System.Xml;
    
        /// <summary>
        /// Represents the RulesFunction flow invoked function.
        /// </summary>
        public class RulesFunction
        {
            private readonly ILogger<RulesFunction> logger;
    
            public RulesFunction(ILoggerFactory loggerFactory)
            {
                logger = loggerFactory.CreateLogger<RulesFunction>();
            }
    
            /// <summary>
            /// Execute the logic app workflow.
            /// </summary>
            /// <param name="ruleSetName">The ruleset name.</param>
            /// <param name="documentType">The document type for the input XML.</param>
            /// <param name="inputXml">The input XML type fact.</param>
            /// <param name="purchaseAmount">The purchase amount value used to create a .NET fact.</param>
            /// <param name="zipCode">The zip code value used to create a .NET fact.</param>
            [FunctionName("RulesFunction")]
            public Task<RuleExecutionResult> RunRules([WorkflowActionTrigger] string ruleSetName, string documentType, string inputXml, int purchaseAmount, string zipCode)
            {
                /***** Summary of steps below *****
                * 1. Get the ruleset to execute.
                * 2. Check if the ruleset was successfully retrieved.
                * 3. Create the rules engine object.
                * 4. Create TypedXmlDocument facts for all XML document facts.
                * 5. Initialize .NET facts.
                * 6. Execute rules engine.
                * 7. Retrieve relevant updates facts and send them back.
                */
    
                try
                {
                    // Get the ruleset based on the ruleset name.
                     var ruleExplorer = new FileStoreRuleExplorer();
                     var ruleSet = ruleExplorer.GetRuleSet(ruleSetName);
    
                    // Check if ruleset exists.
                    if(ruleSet == null)
                    {
                        // Log an error if ruleset not found.
                        this.logger.LogCritical($"RuleSet instance for '{ruleSetName}' was not found(null)");
                        throw new Exception($"RuleSet instance for '{ruleSetName}' was not found.");
                    }
    
                    // Create rules engine instance.
                    var ruleEngine = new RuleEngine(ruleSet: ruleSet);
    
                    // Create one or more typedXmlDcoument facts from one or more input XML documents.
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(inputXml);
                    var typedXmlDocument = new TypedXmlDocument(documentType, doc);
    
                    // Initialize .NET facts.
                    var currentPurchase = new ContosoNamespace.ContosoPurchase(purchaseAmount, zipCode);
    
                    // Provide facts and run the rules engine.
                    ruleEngine.Execute(new object[] { typedXmlDocument, currentPurchase });
    
                    // Send back the relevant results (facts).
                    var updatedDoc = typedXmlDocument.Document as XmlDocument;
                    var ruleExectionOutput = new RuleExecutionResult()
                    {
                        XmlDoc = updatedDoc.OuterXml,
                        PurchaseAmountPostTax = currentPurchase.PurchaseAmount + currentPurchase.GetSalesTax()
                    };
    
                    return Task.FromResult(ruleExectionOutput);
                }
                catch(RuleEngineException ruleEngineException)
                {
                    // Log any rules engine exceptions.
                    this.logger.LogCritical(ruleEngineException.ToString());
                    throw;
                }
            }
    
            /// <summary>
            /// Results from rules execution
            /// </summary>
            public class RuleExecutionResult
            {
                /// <summary>
                /// Rules updated XML document
                /// </summary>
                public string XmlDoc { get; set;}
    
                /// <summary>
                /// Purchase amount after tax
                /// </summary>
                public int PurchaseAmountPostTax { get; set;}
            }
        }
    }
    

    RulesFunction の関数定義には、作業を開始するために使用できる既定の RunRules メソッドが含まれています。 このサンプルの RunRules メソッドでは、Azure Logic Apps Rules Engine にパラメーターを渡す方法を示しています。 この例では、メソッドはルールセット名、入力ドキュメントの種類、XML ファクト、さらなる処理に必要なその他の値を渡します。

    また、<関数名>.cs ファイルは ILogger インターフェイスを持ち、Application Insights リソースへのイベントのロギングのサポートを提供します。 例えば、Application Insights にトレース情報を送信し、その情報をワークフローからのトレース情報とともに格納できます:

    private readonly ILogger<RulesFunction> logger;
    
        public RulesFunction(ILoggerFactory loggerFactory)
        {
            logger = loggerFactory.CreateLogger<RulesFunction>();
        }
        <...>
    
    

    Azure Logic Apps Rules Engine は、次の手順で説明するように動作します。

    1. エンジンは、FileStoreRuleExplorer オブジェクトを使用してルールセットにアクセスします。 ルールセット ファイルは、Standard ロジック アプリの [ルール] ディレクトリに格納されます。

      この例では、ルールセット ファイルは SampleRuleSet.xml と呼ばれ、Microsoft Rules Composer を使用して作成されたか、Microsoft BizTalk Server を使用してエクスポートされたものです。

      var ruleExplorer = new FileStoreRuleExplorer();
      var ruleSet = ruleExplorer.GetRuleSet(ruleSetName);
      
      // Check if the ruleset exists.
      if(ruleSet == null)
      {
          // Log an error if the ruleset isn't found.
          this.logger.LogCritical($"RuleSet instance for '{ruleSetName}' was not found(null)");
          throw new Exception($"RuleSet instance for '{ruleSetName}' was not found.");
      }
      

      重要

      ルールセットは、ファクトへの参照を保持します。 Microsoft Rules Composer は、ファクトのアセンブリを検索して編集用のルールセットを検証します。 Microsoft Rules ComposerSampleRuleSet.xml などのルールセットを開くには、対応する .NET ファクト アセンブリと共にルールセットを配置する必要があります。 それ以外の場合は、例外が発生します。

    2. エンジンは ruleSet オブジェクトを使用して RuleEngine オブジェクトのインスタンスを作成します。

    3. RuleEngine オブジェクトは、Execute メソッドを使用してルールのファクトを受け取ります。

      この例では、Execute メソッドは 2 つのファクト、typedXmlDocument という名前の XML ファクトと currentPurchase という名前の .NET ファクトを受け取ります。

      エンジンの実行後、ファクトの値はエンジンの実行結果の値で上書きされます。

      // Create rules engine instance.
      var ruleEngine = new RuleEngine(ruleSet: ruleSet);
      
      // Create one or more typedXml facts from one or more input XML documents.
      XmlDocument doc = new XmlDocument();
      doc.LoadXml(inputXml);
      var typedXmlDocument = new TypedXmlDocument(documentType, doc);
      
      // Initialize .NET facts.
      var currentPurchase = new ContosoNamespace.ContosoPurchase(purchaseAmount, zipCode);
      
      // Provide facts and run the rules engine.
      ruleEngine.Execute(new object[] { typedXmlDocument, currentPurchase });
      
      // Send back the relevant results (facts).
      var updatedDoc = typedXmlDocument.Document as XmlDocument;
      
    4. エンジンは RuleExecutionResult カスタム クラスを使用して、RunRules メソッドに値を返します。

      var ruleExectionOutput = new RuleExecutionResult()
      {
          XmlDoc = updatedDoc.OuterXml,
          PurchaseAmountPostTax = currentPurchase.PurchaseAmount + currentPurchase.GetSalesTax()
      };
      
      return Task.FromResult(ruleExectionOutput);
      
    5. サンプルの関数コードを独自の関数コードに置き換え、ご自身のシナリオに合わせて既定の RunRules メソッドを編集します。

      この例では、変更を加えずにサンプル コードをそのまま使用します。

コードをコンパイルしてビルドする

コードの記述が完了したら、コンパイルしてビルド エラーが存在しないことを確認します。 関数プロジェクトには、ビルド タスクが自動的に含まれ、.NET ファクト アセンブリを含むカスタム コード ライブラリがコンパイルされ、ワークフローが実行するカスタム関数を検索するロジック アプリ プロジェクトの lib\custom フォルダーに追加されます。 これらのタスクにより、アセンブリが lib\custom\net472 フォルダーに配置されます。

  1. Visual Studio Code で、[Terminal] (ターミナル) メニューから [New Terminal] (新しいターミナル) を選択します。

  2. 表示された作業ディレクトリの一覧から、新しいターミナルの現在の作業ディレクトリとして [関数] を選択します。

    スクリーンショットは、Visual Studio Code、現在の作業ディレクトリを指定するためのプロンプト、選択した [関数] ディレクトリを示しています。

    Visual Studio Code で、コマンド プロンプトが表示されたターミナル ウィンドウが開きます。

  3. [ターミナル] ウィンドウのコマンド プロンプトに、「dotnet restore .\RulesFunction.csproj」と入力します。

    スクリーンショットは、Visual Studio Code、[Terminal] (ターミナル) ウィンドウ、入力された dotnet restore コマンドを示しています。

  4. コマンド プロンプトが再び表示されたら、「dotnet build .\RulesFunction.csproj」と入力します。

    ビルドが成功すると、[Terminal] (ターミナル) ウィンドウに [ビルドが正常に終了しました] と報告されます。

  5. ロジック アプリ プロジェクトに次の項目が存在することを確認します。

    • ワークスペースで、次のフォルダーを展開します: LogicApp>lib\custom>net472net472 という名前のサブフォルダーに、<関数名>.dll という名前のファイルを含む、コードの実行に必要な複数のアセンブリが含まれていることを確認します。

    • ワークスペースで、次のフォルダーを展開します: LogicApp>lib\custom><function-name><function-name> という名前のサブフォルダーに、作成した関数コードに関するメタデータを含む function.json ファイルが含まれていることを確認します。 ワークフロー デザイナーは、このファイルを使用して、コードの呼び出し時に必要な入力と出力を判断します。

    次の例は、ロジック アプリ プロジェクトで生成されたアセンブリとその他のファイルの例を示しています。

    スクリーンショットは、関数プロジェクトとロジック アプリ プロジェクトを含むロジック アプリ ワークスペース (この時点では、生成されたアセンブリや他の必須ファイルが表示されています) を示しています。

ワークフローからルールを呼び出す

コードがコンパイルされたこと、およびロジック アプリ ルールのエンジン プロジェクトにコードの実行に必要なファイルが含まれていることを確認したら、ロジック アプリ プロジェクトに含まれている既定のワークフローを開きます。

  1. ワークスペースの [LogicApp] で、<ワークフロー名> ノードを展開し、workflow.json のショートカット メニューを開き、[デザイナーを開く] を選択します。

    開いたワークフロー デザイナーに、ロジック アプリ プロジェクトに含まれる既定のワークフローが、次のトリガーおよびアクションと共に表示されます。

  2. [このロジック アプリのローカル ルール関数を呼び出す] という名前のアクションを選択します。

    このアクションの情報ペインが右側に開きます。

    スクリーンショットは、Visual Studio Code、ワークフロー デザイナー、既定のワークフロー (トリガーとアクションを含みます) を示しています。

  3. [関数名] パラメーターの値が、実行するルール関数に設定されていることを確認します。 関数で使用するその他のパラメーター値を確認または変更します。

コードとワークフローをデバッグする

  1. Azurite ストレージ エミュレーターを起動するには、次の手順を 3 回 (次の各 Azure Storage サービスに対して 1 回ずつ) 繰り返します。

    • Azure BLOB サービス
    • Azure Queue サービス
    • Azure テーブル サービス
    1. Visual Studio Code の [表示] メニューから [コマンド パレット] を選びます。

    2. 表示されたプロンプトで、[Azurite: Start Blob Service] (Azurite: BLOB サービスの開始) を見つけて選択します。

    3. 表示された作業ディレクトリの一覧から、[LogicApp] を選択します。

    4. [Azurite: Start Queue Service] (Azurite: Queue サービスの開始)[Azurite: Start Table Service] (Azurite: Table サービスの開始) に対して、これらの手順を繰り返します。

    画面の下部にある Visual Studio Code タスク バーに 3 つのストレージ サービスが実行されていることが示されたら、操作は成功です。次に例を示します。

    スクリーンショットは、Azure BLOB サービス、Azure Queue サービス、Azure Table サービスが実行されている Visual Studio Code タスク バーを示しています。

  2. Visual Studio Code のアクティビティ バーで、[Run and Debug] (実行とデバッグ) を選択します。 (キーボード: Ctrl + Shift + D)

    スクリーンショットは、[Run and Debug] (実行とデバッグ) が選択された Visual Studio Code のアクティビティ バーを示しています。

  3. [Run and Debug] (実行とデバッグ) の一覧で、[Attach to logic app (LogicApp)] (ロジック アプリ (LogicApp) にアタッチ) を選択し (まだ選択されていない場合)、[再生] (緑色の矢印) を選択します。

    スクリーンショットは、[Attach to logic app (LogicApp)] (ロジック アプリ (LogicApp) にアタッチ) が選択され、[再生] ボタンが選択された [Run and Debug] (実行とデバッグ) の一覧を示しています。

    [Terminal] (ターミナル) ウィンドウが開き、デバッグ プロセスが開始したことを示します。 [Debug Console] (デバッグ コンソール) ウィンドウが表示され、デバッグの状態が表示されます。 Visual Studio Code の下部にあるタスク バーがオレンジ色に変わり、.NET デバッガーが読み込まれたことを示します。

  4. [Run and Debug] (実行とデバッグ) の一覧で、[Attach to .NET Functions (Functions)] (.NET Functions (Functions) にアタッチ) を選択し、[再生] (緑色の矢印) を選択します。

    スクリーンショットは、[Attach to .NET Functions (Functions)] (.NET Functions (Functions) にアタッチ) が選択され、[再生] ボタンが選択された [Run and Debug] (実行とデバッグ) の一覧を示しています。

  5. ブレークポイントを設定するには、関数定義 (<関数名>.cs) またはワークフロー定義 (workflow.json) で、ブレークポイントが必要な行番号を見つけて、左側の列を選択します。次に例を示します。

    スクリーンショットは、Visual Studio Code および開いている関数コード ファイル (コード内の行にブレークポイントが設定されています) を示しています。

  6. ワークフローで要求トリガーを手動で実行するには、ワークフローの [概要] ページを開きます。

    1. ロジック アプリ プロジェクトから workflow.json ファイルのショートカット メニューを開き、[概要] を選択します。

      ワークフローの [概要] ページには、ワークフローを手動で開始する場合のために [トリガーの実行] ボタンが用意されています。 [関数名][コールバック URL] の値は、ワークフロー内の要求トリガーによって作成された呼び出し可能なエンドポイントの URL です。 この URL に要求を送信して、他のアプリ (他のロジック アプリ ワークフローなど) からワークフローをトリガーできます。

      スクリーンショットは、Visual Studio Code と、ワークフローの開いている [概要] ページを示しています。

  7. [概要] ページのツール バーで、[トリガーの実行] を選択します。

    ワークフローの実行が開始されると、デバッガーによって最初のブレークポイントがアクティブになります。

  8. [実行] メニューまたはデバッガーのツール バーで、デバッグ アクションを選択します。

    ワークフローの実行が完了すると、[概要] ページに、完了した実行とその実行に関する基本的な詳細が表示されます。

  9. ワークフロー実行の詳細を確認するには、完了した実行を選択します。 または、[実行時間] 列の横にある一覧から [Show run] (実行の表示) を選択します。

    スクリーンショットは、Visual Studio Code と完了したワークフローの実行を示しています。