共用方式為


使用 Visual Studio Code 建立 Azure Logic Apps 規則引擎專案

適用於:Azure Logic Apps (標準)

當您想要在 Azure Logic Apps 中整合商業規則與標準工作流程時,您可以使用 Visual Studio Code 建立和建置 Azure Logic Apps 規則引擎專案。 規則會控管商務程序運作方式的商業規則。

本操作指南說明如何建立 Azure Logic Apps 規則引擎專案:

  • 建立 Azure Logic Apps 規則引擎專案的先決條件和設定,包括使用 Microsoft Rules Composer 為專案建立商務規則。

  • 如果您有任何規則,請從Microsoft BizTalk Server 導出現有的規則。

  • 使用 Visual Studio Code 建立 Azure Logic Apps 規則引擎的標準邏輯應用程式專案。

必要條件

建立專案之前

若要協助您確保規則引擎專案成功,請檢閱並執行下列一般工作和最佳做法:

  1. 決定商務規則如何融入您的商務程式。

  2. 規劃如何將商務規則併入您的應用程式。

  3. 識別您想要在應用程式中以規則表示的商業規則。

    「商業規則」一詞可以參考許多事項。 例如,商業規則可能是「採購單大於 500 美元需要經理核准」。

  4. 識別規則元素的數據源。 您可以選擇性地定義詞彙,這是代表基礎系結的網域特定名詞。

  5. 定義要從詞彙定義或直接從數據系結使用的規則。 從這些規則中,建立代表商業規則的規則集。

從 BizTalk Server Microsoft 導出規則

若要從 BizTalk Server 重複使用現有的規則Microsoft,您可以匯出這些規則。 不過,目前不支援 DB 事實。 在匯出規則之前,請先使用 Microsoft BizTalk 規則編輯器移除或重構成其他類型的事實。

  1. Microsoft BizTalk Server,啟動 商務規則引擎部署精靈

  2. 在 [ 歡迎使用規則引擎部署精靈 ] 頁面上,選取 [ 下一步]。

  3. 在 [ 部署工作 ] 頁面上,選取 [從資料庫匯出原則/詞彙至檔案],然後選取 [ 下一步]。

  4. 在 [ 原則存放區 ] 頁面上的 [SQL Server 名稱] 列表中,選取您的 SQL Server。 在所選伺服器清單中的 [組態資料庫] 中,選取 [BizTalkRuleEngineDb],然後選取 [ 下一步]。

  5. 在 [ 匯出原則 /詞彙] 頁面上,從 [ 原則 ] 列表中,選取您想要的原則。 若要尋找並選擇定義檔,請選取 [ 瀏覽]。

  6. 在您準備就緒後,選取 [下一步]。

  7. 確認伺服器、資料庫和原則或詞彙資訊,然後選取 [ 下一步]。

  8. 匯入或匯出完成後,選取 [ 下一步]。

  9. 檢閱匯入或導出的完成狀態,然後選取 [ 完成]。

建立 Azure Logic Apps 規則引擎專案

  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
    邏輯應用程式: LogicApp
    工作流程範本:
    - 具狀態工作流程
    - 無狀態工作流程
    具狀態工作流程
    工作流程名稱 MyRulesWorkflow
  7. 選取 [在目前視窗中開啟]

    完成此步驟之後,Visual Studio Code 會建立工作區,其中包含函式專案和邏輯應用程式規則引擎專案,例如:

    此螢幕擷取畫面顯示 Visual Studio Code 與已建立的工作區。

    節點 描述
    < workspace-name> 包含函式專案和邏輯應用程式工作流程專案。
    功能 包含函式專案的成品。 例如,<function-name>.cs 檔案是程式碼檔案,您可以在其中撰寫程式碼。
    LogicApp 包含邏輯應用程式規則引擎專案的成品,包括工作流程。

撰寫規則引擎程序代碼

  1. 在您的工作區中,展開 [函式] 節點 (如果尚未展開)。

  2. 開啟函<檔案,在此範例中名為 RulesFunction.cs

    依預設,此檔案包含範例程式碼,其中包含下列程式碼元素,以及先前提供的範例值 (如適用):

    • 命名空間名稱
    • 類別名稱
    • 函式名稱
    • 函數參數
    • 傳回類型
    • 複雜類型

    下列範例顯示名為 RulesFunction之函式的完整範例程式代碼:

    //------------------------------------------------------------
    // Copyright (c) Microsoft Corporation. All rights reserved.
    //------------------------------------------------------------
    
    namespace Contoso
    {
         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.Azure.Workflows.RuleEngine.Common;
         using Microsoft.Extensions.Logging;
         using System.Xml;
         using System.Text;
    
         /// <summary>
         /// Represents the RulesFunction flow invoked function.
         /// </summary>
         public class RulesFunction
         {
             private readonly ILogger<RulesFunction> logger;
    
             private FileStoreRuleExplorer ruleExplorer;
    
             public RulesFunction(ILoggerFactory loggerFactory)
             {
                 logger = loggerFactory.CreateLogger<RulesFunction>();
                 this.ruleExplorer = new FileStoreRuleExplorer(loggerFactory); 
             }
    
             /// <summary>
             /// Executes the logic app workflow.
             /// </summary>
             /// <param name="ruleSetName">The rule set name.</param>
             /// <param name="documentType">document type of input xml.</param>
             /// <param name="inputXml">input xml type fact</param>
             /// <param name="purchaseAmount">purchase amount, value used to create .NET fact </param>
             /// <param name="zipCode">zip code value used to create .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 rule set to Execute 
                  * 2. Check if the rule set was retrieved successfully
                  * 3. create the rule engine object
                  * 4. Create TypedXmlDocument facts for all xml document facts
                  * 5. Initialize .NET facts
                  * 6. Execute rule engine
                  * 7. Retrieve relevant updates facts and send them back
             */
    
                 try
                 {
                     var ruleSet = this.ruleExplorer.GetRuleSet(ruleSetName);
    
                     // Check if ruleset exists
                     if(ruleSet == null)
                     {
                         // Log an error in finding the rule set
                         this.logger.LogCritical($"RuleSet instance for '{ruleSetName}' was not found(null)");
                         throw new Exception($"RuleSet instance for '{ruleSetName}' was not found.");
                     }             
    
                     // Create rule engine instance
                     var ruleEngine = new RuleEngine(ruleSet: ruleSet);
    
                     // Create a typedXml Fact(s) from input xml(s)
                     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 to rule engine and run it
                     ruleEngine.Execute(new object[] { typedXmlDocument, currentPurchase });
    
                     // Send the relevant results(facts) back
                     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 rule engine exceptions
                     this.logger.LogCritical(ruleEngineException.ToString());
                     throw;
                 }
                 catch(XmlException xmlException)
                 {
                     // Log any xml exceptions
                     this.logger.LogCritical("Encountered exception while handling xml. " + xmlException.ToString());
                     throw;
                 }
                 catch(Exception ex)
                 {
                     // Log any other exceptions
                     this.logger.LogCritical(ex.ToString());
                     throw;
                 }
             }
    
             /// <summary>
             /// Results of the rule execution
             /// </summary>
             public class RuleExecutionResult
             {
                 /// <summary>
                 /// rules updated xml document
                 /// </summary>
                 public string XmlDoc { get; set;}
    
                 /// <summary>
                 /// Purchase amount post tax
                 /// </summary>
                 public int PurchaseAmountPostTax { get; set;}
             }
         }
    }
    

    RulesFunction 函式定義包含可用來開始使用的預設 RunRules 方法。 這個範例 RunRules 方法示範如何將參數傳遞至 Azure Logic Apps 規則引擎。 在此範例中,方法會傳遞規則集名稱、輸入檔類型、XML 事實和其他值,以便進一步處理。

    < function-name>.cs 檔案也包含 ILogger 介面,其支援將事件記錄至 Application Insights 資源。 您可以將追蹤資訊傳送至 Application Insights,並將該資訊與工作流程中的追蹤資訊一起儲存。 < 功能名稱>.cs 檔案也包含存取規則集的 FileStoreRuleExplorer 物件。 如您所見,FileStoreRuleExplorer 的建構函式會使用 loggerFactory,也將遙測資訊傳送至 Application Insights:

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

    Azure Logic Apps 規則引擎的運作方式如下的步驟所述:

    1. 引擎會 FileStoreRuleExplorer 使用 物件來存取規則集。 規則集檔案會儲存在 Standard 邏輯應用程式的 Rules 目錄中。

      在此範例中,規則集檔案稱為 SampleRuleSet.xml,這是使用 Microsoft Rules Composer 建立,或使用 bizTalk Server Microsoft導出

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

    重要

    規則集會保存其事實的參考。 Microsoft Rules Composer 會尋找事實的元件,以驗證規則集以進行編輯。 若要開啟規則集,例如SampleRuleSet.xml在 Microsoft Rules Composer 中,您必須將它們放在對應的 .NET 事實元件中。 否則,您會收到例外狀況。

    1. 引擎會 ruleSet 使用 物件來建立 對象的實例 RuleEngine

    2. 物件 RuleEngine 會使用 Execute 方法接收規則的事實。

      在此範例中 Execute ,方法會接收兩個事實:名為 typedXmlDocument 的 XML 事實和名為 currentPurchase的 .NET 事實。

      在引擎執行之後,事實的值會以引擎執行所產生的值覆寫:

    // Create rule engine instance
    var ruleEngine = new RuleEngine(ruleSet: ruleSet);
    // Create a typedXml Fact(s) from input xml(s)
    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 to rule engine and run it
    ruleEngine.Execute(new object[] { typedXmlDocument, currentPurchase });
    // Send the relevant results(facts) back
       var updatedDoc = typedXmlDocument.Document as XmlDocument;
    
    1. 引擎會 RuleExecutionResult 使用自定義類別將值 RunRules 傳回至 方法:
    var ruleExectionOutput = new RuleExecutionResult()
                 {
                     XmlDoc = updatedDoc.OuterXml,
                     PurchaseAmountPostTax = currentPurchase.PurchaseAmount + currentPurchase.GetSalesTax()
                 };
    
                 return Task.FromResult(ruleExectionOutput);
    
    1. 將範例函式程式碼取代為您自己的函式程式碼,並針對您自己的案例編輯預設的 RunRules 方法。

      此範例會繼續使用範例程序代碼,而不需要進行任何變更。

編譯和建置程式碼

完成撰寫程式碼之後,請編譯以確定不存在任何建置錯誤。 您的函式專案會自動包含建置工作,這些工作會編譯,然後將任何自定義程式代碼連結庫,包括 .NET 事實元件,新增至 邏輯應用程式專案中的 lib\custom 資料夾,其中工作流程會尋找要執行的自定義函式。 這些工作會將組件放在 lib\custom\net472 資料夾中。

  1. 在 Visual Studio Code 的 [終端機] 功能表中,選取 [新增終端機]

  2. 從出現的工作目錄清單中,選取 [函式] 作為新終端機的目前工作目錄。

    此螢幕擷取畫面顯示 Visual Studio Code、目前工作目錄的提示,以及選取的 Functions 目錄。

    Visual Studio Code 會開啟具有命令提示字元的終端機視窗。

  3. 在終端機視窗中,於命令提示字元中,輸入 dotnet restore .\RulesFunction.csproj

    此螢幕擷取畫面顯示 Visual Studio Code、終端機視窗和已完成的 dotnet restore 命令。。

  4. 命令提示字元重新出現之後,輸入 dotnet build .\RulesFunction.csproj

    如果您的建置成功,[終端機] 視窗會報告 [建置成功]

  5. 確認邏輯應用程式專案中有下列項目:

    • 在您的工作區中,展開下列資料夾:LogicApp>lib\custom>net472。 確認名為 net472 的子資料夾包含執行程式代碼所需的多個元件,包括名為 <function-name> 的檔案.dll。

    • 在您的工作區中,展開下列資料夾:LogicApp>lib\custom><function-name>。 確認名為 <function-name> 的子資料夾包含 function.json 檔案,其包含您撰寫的函式程式碼的相關中繼資料。 工作流程設計工具會使用此檔案來判斷呼叫程式碼時所需的輸入和輸出。

    下列範例顯示邏輯應用程式專案中產生的範例組件和其他檔案:

    此螢幕快照顯示具有函式專案和邏輯應用程式專案的邏輯應用程式工作區,現在包含產生的元件和其他必要檔案。

從工作流程呼叫規則

確認程式代碼會編譯,且邏輯應用程式規則引擎專案具有執行程式代碼所需的檔案之後,請開啟邏輯應用程式專案隨附的預設工作流程。

  1. 在工作區中的 LogicApp 下,展開 <workflow-name> 節點,開啟 workflow.json 的捷徑功能表,然後選取 [開啟設計工具]

    在開啟的工作流程設計工具上,邏輯應用程式專案隨附的預設工作流程會顯示,並具有下列觸發程序和動作:

    • 內建 要求觸發程式,名為 收到 HTTP 要求時」。
    • 此邏輯應用程式中名為呼叫本機規則函式的內建動作。
    • 名為 Response 的內建回應動作,只有在您使用要求觸發程式時,才會用來回復呼叫端。
  2. 選取名為 呼叫此邏輯應用程式中本機規則函式的動作。

    動作的資訊窗格隨即開啟至右側。

    此螢幕擷取畫面顯示 Visual Studio Code、工作流程設計工具,以及具有觸發程序和動作的預設工作流程。

  3. 檢閱並確認函 式名稱 參數值已設定為您要執行的規則函式。 檢閱或變更函式使用的任何其他參數值。

對程式碼和工作流程偵錯

  1. 重複下列步驟以啟動 Azurite 儲存體模擬器次:下列 Azure 儲存體服務各一次:

    • Azure Blob 服務
    • Azure 佇列服務
    • Azure 表格服務
    1. 從 Visual Studio Code [檢視] 功能表,選取 [命令選擇區]

    2. 在出現的提示中,尋找並選取 [Azurite:啟動 Blob 服務]

    3. 從出現的工作目錄清單中,選取 [LogicApp]

    4. 針對 [Azurite:啟動佇列服務] 和 [Azurite:啟動表格服務] 重複這些步驟。

    當畫面底部的 Visual Studio Code 工作列顯示三個儲存體服務執行中時,您便已成功,例如:

    此螢幕擷取畫面顯示正在執行的 Azure Blob 服務、Azure 佇列服務和 Azure 表格服務的 Visual Studio Code 工作列。

  2. 在 Visual Studio Code 活動列上,選取 [執行並偵錯]。 (鍵盤:Ctrl+Shift+D)

    此螢幕擷取畫面顯示選取了 [執行並偵錯] 的 Visual Studio Code 活動列。

  3. 從 [執行並偵錯] 清單,選取 [連結至邏輯應用程式 (LogicApp)],如果尚未選取,則選取 [播放] (綠色箭號)。

    此螢幕擷取畫面顯示 [執行並偵錯] 清單,其中選取了 [連結到邏輯應用程式] 和 [播放] 按鈕。

    [終端機] 視窗隨即開啟,並顯示已啟動的偵錯程序。 [偵錯主控台] 視窗隨即出現,並顯示偵錯狀態。 在 Visual Studio Code 底部,工作列變成橙色,表示 .NET 偵錯工具已載入。

  4. 若要設定任何斷點,請在函式定義(<function-name>.cs)或工作流程定義(workflow.json)中尋找您要斷點的行號,然後選取左側的數據行,例如:

    此螢幕擷取畫面顯示 Visual Studio Code 和開啟的函式程式碼檔案,其中為程式碼行設定了中斷點。

  5. 若要在工作流程中手動執行要求觸發程序,請開啟工作流程的 [概觀] 頁面。

    1. 從邏輯應用程式專案,開啟 workflow.json 檔案的捷徑功能表,然後選取 [概觀]

      在工作流程的 [概觀] 頁面上,當您想要手動啟動工作流程時,可以使用 [執行觸發程序] 按鈕。 在 [工作流程屬性] 下,[回呼 URL] 值是工作流程中 [要求] 觸發程式所建立之可呼叫端點的 URL。 您可以將要求傳送至此 URL,以從其他應用程式觸發工作流程,包括其他邏輯應用程式工作流程。

      此螢幕擷取畫面顯示 Visual Studio Code 和開啟了工作流程的 [概觀] 頁面。

  6. 在 [概觀] 頁面工具列上,選取 [執行觸發程序]

    工作流程開始執行之後,偵錯工具會啟動您的第一個中斷點。

  7. 在 [執行] 功能表或偵錯工具工具列上,選取 [偵錯動作]

    工作流程執行完成之後,[概觀] 頁面會顯示已完成的執行,以及該執行的基本詳細資料。

  8. 若要檢閱工作流程執行的詳細資訊,請選取已完成的執行。 或者,從 [持續時間] 資料行旁邊的清單,選取 [顯示執行]

    此螢幕擷取畫面顯示 Visual Studio Code 和已完成的工作流程執行。

  9. 若要使用規則引擎專案將邏輯應用程式部署至 Azure Logic Apps,請遵循 準備部署中的步驟。