다음을 통해 공유


Visual Studio Code를 사용하여 Azure Logic Apps 규칙 엔진 프로젝트 만들기(미리 보기)

적용 대상: Azure Logic Apps(표준)

Important

이 기능은 미리 보기로 제공되고 Microsoft Azure 미리 보기의 추가 사용 약관이 적용됩니다.

비즈니스 논리를 Azure Logic Apps의 표준 워크플로와 통합하려는 경우 Visual Studio Code를 사용하여 Azure Logic Apps 규칙 엔진 프로젝트를 만들고 빌드할 수 있습니다. 규칙은 비즈니스 프로세스 작동 방식에 대한 비즈니스 논리를 제어합니다.

이 방법 가이드에서는 Azure Logic Apps 규칙 엔진 프로젝트를 만드는 방법을 설명합니다.

  • Microsoft 규칙 작성기를 사용하여 프로젝트에 대한 비즈니스 규칙 만들기를 포함하여 Azure Logic Apps 규칙 엔진 프로젝트를 만들기 위한 필수 구성 요소 및 설정입니다.

  • Microsoft BizTalk Server에서 기존 규칙을 내보냅니다(있는 경우).

  • Visual Studio Code를 사용하여 Azure Logic Apps 규칙 엔진에 대한 표준 논리 앱 프로젝트를 만듭니다.

필수 조건

프로젝트를 만들기 전에

성공적인 규칙 엔진 프로젝트를 보장하려면 다음 일반 작업 및 모범 사례를 검토하고 수행합니다.

  1. 비즈니스 규칙이 비즈니스 프로세스에 적합한 방식을 결정합니다.

  2. 비즈니스 규칙을 애플리케이션에 통합하는 방법을 계획합니다.

  3. 애플리케이션의 규칙으로 표시하려는 비즈니스 논리를 식별합니다.

    "비즈니스 논리"라는 용어는 많은 항목을 참조할 수 있습니다. 예를 들어 비즈니스 논리는 "500달러를 초과하는 구매 주문에는 관리자 승인이 필요합니다."일 수 있습니다.

  4. 규칙 요소의 데이터 원본을 식별합니다. 필요에 따라 기본 바인딩을 나타내는 도메인별 명명법인 어휘를 정의할 수 있습니다.

  5. 어휘 정의 또는 데이터 바인딩에서 직접 사용할 규칙을 정의합니다. 이러한 규칙에서 비즈니스 논리를 나타내는 규칙 집합을 만듭니다.

Microsoft BizTalk Server에서 규칙 내보내기

Microsoft BizTalk Server에서 기존 규칙을 다시 사용하려면 해당 규칙을 내보낼 수 있습니다. 그러나 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. 다음 프롬프트에 따라 다음 예제 값을 제공합니다.

    Item 예제 값
    함수 프로젝트의 함수 이름 RulesFunction
    함수 프로젝트의 네임스페이스 이름 Contoso.Enterprise
    워크플로 템플릿:
    - 상태 저장 워크플로
    - 상태 비저장 워크플로
    상태 저장 워크플로
    워크플로 이름 MyRulesWorkflow
  7. 현재 창에서 열기를 선택합니다.

    이 단계를 완료한 후 Visual Studio Code는 함수 프로젝트와 논리 앱 규칙 엔진 프로젝트를 포함하는 작업 영역을 만듭니다. 예를 들면 다음과 같습니다.

    스크린샷은 생성된 작업 영역이 있는 Visual Studio Code를 보여줍니다.

    노드 설명
    <workspace-name> 함수 프로젝트와 논리 앱 워크플로 프로젝트를 모두 포함합니다.
    Function 함수 프로젝트에 대한 아티팩트를 포함합니다. 예를 들어 <function-name.cs> 파일은 코드를 작성할 수 있는 코드 파일입니다.
    LogicApp 워크플로를 포함하여 논리 앱 규칙 엔진 프로젝트에 대한 아티팩트를 포함합니다.

규칙 엔진 코드 작성

  1. 아직 확장되지 않은 경우 작업 영역에서 Functions 노드를 확장합니다.

  2. 이 예제에서 <RulesFunction.cs 명명된 function-name>.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 typedXmlDocument 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 ruleExecutionOutput = new RuleExecutionResult()
                    {
                        XmlDoc = updatedDoc.OuterXml,
                        PurchaseAmountPostTax = currentPurchase.PurchaseAmount + currentPurchase.GetSalesTax()
                    };
    
                    return Task.FromResult(ruleExecutionOutput);
                }
                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 규칙 엔진에 매개 변수를 전달하는 방법을 보여줍니다. 이 예제에서 메서드는 추가 처리를 위해 규칙 집합 이름, 입력 문서 형식, XML 팩트 및 기타 값을 전달합니다.

    <function-name>.cs 파일에는 Application Insights 리소스에 이벤트 로깅을 지원하는 ILogger 인터페이스도 포함되어 있습니다. Application Insights에 추적 정보를 보내고 워크플로의 추적 정보와 함께 해당 정보를 저장할 수 있습니다. 예를 들면 다음과 같습니다.

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

    Azure Logic Apps 규칙 엔진은 다음 단계에 설명된 대로 작동합니다.

    1. 엔진은 개체를 FileStoreRuleExplorer 사용하여 규칙 집합에 액세스합니다. 규칙 집합 파일은 표준 논리 앱의 규칙 디렉터리에 저장됩니다.

      이 예제에서는 규칙 집합 파일을 호출SampleRuleSet.xml합니다. 이 파일은 Microsoft 규칙 작성기를 사용하여 만들거나 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.");
      }
      

      Important

      규칙 집합에는 해당 사실에 대한 참조가 있습니다. Microsoft 규칙 작성기는 팩트의 어셈블리를 검색하여 규칙 집합의 편집 유효성을 검사합니다. Microsoft 규칙 작성기에서와 같은 SampleRuleSet.xml 규칙 집합을 열려면 해당 .NET 팩트 어셈블리와 함께 배치해야 합니다. 그렇지 않으면 예외가 발생합니다.

    2. 엔진은 개체를 ruleSet 사용하여 개체의 인스턴스를 만듭니다 RuleEngine .

    3. 개체는 RuleEngine 메서드를 사용하여 규칙의 팩트를 받습니다 Execute .

      이 예제에서 메서드는 Execute 이름이 지정된 XML 팩트와 이름이 typedXmlDocument .NET 팩트라는 두 가지 팩트를 받습니다 currentPurchase.

      엔진이 실행되면 팩트의 값은 엔진 실행으로 인한 값으로 덮어씁니다.

      // 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 ruleExecutionOutput = new RuleExecutionResult()
      {
          XmlDoc = updatedDoc.OuterXml,
          PurchaseAmountPostTax = currentPurchase.PurchaseAmount + currentPurchase.GetSalesTax()
      };
      
      return Task.FromResult(ruleExecutionOutput);
      
    5. 샘플 함수 코드를 사용자 고유의 코드로 바꾸고 사용자 고유의 시나리오에 대한 기본 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에 대한 바로 가기 메뉴를 열고 디자이너 열기를 선택합니다.

    열리는 워크플로 디자이너에서 논리 앱 프로젝트에 포함된 기본 워크플로가 다음 트리거 및 작업과 함께 표시됩니다.

  2. 이 논리 앱에서 로컬 규칙 호출 함수라는 작업을 선택합니다.

    작업의 정보 창이 오른쪽에 열립니다.

    스크린샷은 트리거 및 작업이 있는 Visual Studio Code, 워크플로 디자이너 및 기본 워크플로를 보여줍니다.

  3. 함수 이름 매개 변수 값이 실행하려는 규칙 함수로 설정되어 있는지 검토하고 확인합니다. 함수에서 사용하는 다른 매개 변수 값을 검토하거나 변경합니다.

코드 및 워크플로 디버그

  1. 다음 단계를 반복하여 다음 Azure Storage 서비스에 대해 각각 한 번씩, Azurite 스토리지 에뮬레이터를 번 시작합니다.

    • Azure Blob Service
    • Azure 큐 서비스
    • Azure Table Service
    1. Visual Studio Code 보기 메뉴에서 명령 팔레트를 선택합니다.

    2. 표시되는 프롬프트에서 Azurite: Blob 서비스 시작을 찾아 선택합니다.

    3. 표시되는 작업 디렉터리 목록에서 LogicApp을 선택합니다.

    4. Azurite: 큐 서비스 시작Azurite: 테이블 서비스 시작에 대해 다음 단계를 반복합니다.

    화면 아래쪽의 Visual Studio Code 작업 표시줄에 실행 중인 세 가지 스토리지 서비스가 표시되면 성공합니다. 예를 들면 다음과 같습니다.

    스크린샷은 Azure Blob Service, Azure Queue Service 및 Azure Table Service가 실행 중인 Visual Studio Code 작업 표시줄을 보여줍니다.

  2. Visual Studio Code 활동 막대에서 실행 및 디버그를 선택합니다. (키보드: Ctrl+Shift+D)

    스크린샷은 실행 및 디버그가 선택된 Visual Studio Code 작업 표시줄을 보여줍니다.

  3. 실행 및 디버그 목록에서 논리 앱(LogicApp)에 연결을 선택하고 아직 선택하지 않은 경우 재생(녹색 화살표)을 선택합니다.

    스크린샷은 논리 앱에 연결이 선택되고 재생 단추가 선택된 실행 및 디버그 목록을 보여줍니다.

    터미널 창이 열리고 시작된 디버깅 프로세스가 표시됩니다. 그러면 디버그 콘솔 창이 나타나고 디버깅 상태가 표시됩니다. Visual Studio Code 아래쪽에서 작업 표시줄이 주황색으로 바뀌어 .NET 디버거가 로드되었음을 나타냅니다.

  4. 실행 및 디버그 목록에서 .NET 함수(Functions)에 연결을 선택한 다음 재생(녹색 화살표)을 선택합니다.

    스크린샷은 NET 함수에 연결이 선택되고 재생 단추가 선택된 실행 및 디버그 목록을 보여줍니다.

  5. 중단점을 설정하려면 함수 정의(<함수 이름>.cs) 또는 워크플로 정의(workflow.json)에서 중단점을 원하는 줄 번호를 찾고 왼쪽에 있는 열을 선택합니다. 예를 들면 다음과 같습니다.

    스크린샷은 코드의 줄에 대한 중단점이 설정된 Visual Studio Code 및 열린 함수 코드 파일을 보여줍니다.

  6. 워크플로에서 요청 트리거를 수동으로 실행하려면 워크플로의 개요 페이지를 엽니다.

    1. 논리 앱 프로젝트에서 workflow.json 파일의 바로 가기 메뉴를 열고 개요를 선택합니다.

      워크플로의 개요 페이지에서 워크플로를 수동으로 시작하려는 경우 트리거 실행 단추를 사용할 수 있습니다. 워크플로 속성에서 콜백 URL 값은 워크플로의 요청 트리거에 의해 만들어진 호출 가능한 엔드포인트의 URL입니다. 다른 논리 앱 워크플로를 포함하여 다른 앱에서 워크플로를 트리거하기 위해 이 URL에 요청을 보낼 수 있습니다.

      스크린샷은 Visual Studio Code 및 워크플로의 개요 페이지가 열려 있는 것을 보여줍니다.

  7. 개요 페이지 도구 모음에서 트리거 실행을 선택합니다.

    워크플로가 실행하기 시작하면 디버거가 첫 번째 중단점을 활성화합니다.

  8. 실행 메뉴 또는 디버거 도구 모음에서 디버그 작업을 선택합니다.

    워크플로 실행이 완료되면 개요 페이지에 완료된 실행과 해당 실행에 대한 기본 세부 정보가 표시됩니다.

  9. 워크플로 실행에 대한 자세한 내용을 검토하려면 완료된 실행을 선택합니다. 또는 기간 열 옆의 목록에서 실행 표시를 선택합니다.

    스크린샷은 Visual Studio Code 및 완료된 워크플로 실행을 보여줍니다.