다중 행 규칙 실행기

속성에 대해 원하는 값을 계산하기 위해 다중 행 규칙을 빌드해야 하는 경우가 있습니다. IBM® Verify 간단한 단일 행 규칙부터 보다 복잡한 다중 행 규칙까지 모두 설정할 수 있습니다.

단일 행 구문 규칙에 대해서는 ‘속성 함수’를 참조하십시오.

다중 행 규칙의 요소

다중 행 규칙은 YAML 형식으로 작성됩니다. 이 규칙은 YAML 문서의 형식화 요구로 제한됩니다. 사용되는 YAML 구문 분석기는 대부분의 YAML 1.1과 1.2를 지원합니다.

다음 용어를 이해해야 합니다.
명령문
명령문은 규칙의 구성 요소이며 여러 유형일 수 있습니다. 예를 들어, return문은 제공된 표현식을 계산하고 표현식을 규칙 값으로 리턴합니다.
블록
블록은 바인드된 명령문 콜렉션입니다. 규칙은 statements라고 하는 최상위 레벨 블록으로 시작됩니다. 블록은 특정 명령문 유형 내에 있을 수 있습니다. 예를 들어, if.block은 해당 if.match문이 true로 평가될 때 실행할 명령문의 콜렉션입니다.
블록 컨텍스트(Block context)
블록 컨텍스트는 해당 블록 내에서 사용 가능한 변수의 콜렉션입니다. 하위 블록은 상위 블록의 컨텍스트에 액세스할 수 있습니다. 상위 블록은 하위 블록의 컨텍스트에 액세스할 수 없습니다.
표현식
표현식은 단일 행으로 된 표현식과 동일한 구문을 사용하는 스니펫입니다. ‘속성 함수’ 항목을 참조하십시오.

지원되는 명령문 유형

세 가지 유형의 명령문이 지원됩니다.
  • 컨텍스트
  • 리턴
  • If

context문

context문은 값을 초기화하고 이름 지정된 변수에 값을 지정하는 데 사용됩니다. 두 가지 연산자를 지원합니다.
:=
이 연산자는 명령문이 평가되는 컨텍스트 블록 내에서 새 변수를 초기화하는 데 사용됩니다. 예를 들어, 변수가 if.block 내에서 초기화되면 후속 명령문의 해당 블록 외부에서 사용할 수 없습니다.
=
이 연산자는 기존 변수에 값을 지정하는 데 사용됩니다. 변수는 현재 컨텍스트 블록이나 상위 블록에 있을 수 있습니다.
형식은 context: {{varname}} := {{expression}}입니다. 동일한 블록 또는 하위 블록에서 후속 명령문의 {{varname}}에 액세스하기 위해 context.{{varname}}을 사용합니다.

return문

return문은 실행을 종료하고 계산된 값을 즉시 리턴하도록 규칙 엔진에 표시하는 데 사용됩니다.

형식은 return: {{expression}}입니다.

If문

if문은 조건부 블록을 빌드하는 데 사용됩니다. 이전 두 개의 명령문과 달리 여러 특성으로 구성됩니다.

표 1.
이름 설명 형식
match 이 조건이 참으로 평가되면, 해당 block 코드가 실행됩니다. match: 1 == 2
block match가 true로 평가되면 실행해야 하는 명령문의 바인드된 블록입니다. 명령문의 표준 YAML 배열
elsifs match가 true로 평가되지 않은 경우에 평가되는 else-if 조건의 배열입니다. 중첩된 if문인 YAML 배열
else match 및 모든 elseifs.match가 true로 평가되지 않는 경우에 평가되는 명령문의 블록입니다. 명령문의 YAML 배열

추적 로깅

다중 라인 규칙에 트레이스 로깅을 추가하여 디버그 로그를 전송할 수 있습니다. 추적 로깅 속성은 추적 모드가 활성화된 상태에서 규칙이 실행될 때 적용됩니다. 추적 로깅은 및 debugx 속성을 debug 통해 지원됩니다.

debug 명령문

debug 문은 주어진 식을 실행하고 반환된 값을 기록하도록 지시하는 데 사용됩니다. 이 표현식은 항상 문자열로 평가되어야 합니다.

형식 - debug: {{expression}}

debugx 차단

fieldsdebugx 블록은 두 가지 속성, 즉 log 와 로 구성됩니다.

이름 설명 형식
로그(log) 제공된 표현식이 평가되고, 반환된 값이 기록됩니다. 이 표현식은 항상 문자열로 평가되어야 합니다. log: {{expression}}
필드 로그와 함께 전송되는 사용자 정의 메타데이터 필드. 키-값 쌍의 형태로 제공됩니다. 각 쌍의 값은 문자열로 평가되어야 하는 식입니다. {{field_key}}: {{expression}}

추적 로깅을 보여주는 예제 함수는 해당 섹션을 참조하십시오.

스니펫

이 스니펫 목록은 완전하지 않으며 가능한 규칙 사용을 모두 포함하지는 않습니다. 하지만 이 목록은 그대로 사용하거나 확장할 수 있는 몇 가지 샘플을 제공합니다.

참고: 다중 행 구문은 형식을 YAML 따르므로, 사용자 정의 규칙이 제대로 작동하려면 올바른 들여쓰기가 필수적입니다.

관리자의 표시 이름 확보

statements:
  - context: manager := user.getManager()
  - context: userExists := has(context.manager.name)
  - context: >
      givenNameExists := context.userExists
      && has(context.manager.name.givenName) 
      && context.manager.name.givenName != ""
  - context: familyNameExists := context.userExists && has(context.manager.name.familyName) && context.manager.name.familyName != ""
  - context: formattedExists := context.userExists && has(context.manager.name.formatted) && context.manager.name.formatted != ""
  - if:
      match: context.formattedExists
      block:
        - return: context.manager.name.formatted
      elseifs:
        - match: context.givenNameExists
          block:
            - if:
                match: context.familyNameExists
                block:
                  - context: managerName := context.manager.name.familyName + ", " + context.manager.name.givenName
                  - return: context.managerName
                else:
                  - return: context.manager.name.givenName
        - match: context.familyNameExists
          block:
            - return: context.manager.name.familyName
- return: string("Not Available")

이메일 도메인 변환

statements:
  - context: "workEmails := has(user.emails) ? user.emails.filter(e, e.type == 'work') : []"
  - context: "workEmail := size(context.workEmails) > 0 ? context.workEmails[0].value : ''"
  - if:
      match: context.workEmail != ""
      block:
        - context: cn := context.workEmail.substring(0, context.workEmail.lastIndexOf('@'))
        - if:
            match: context.cn != ""
            block:
              - return: context.cn + "@github.com"
  - return: ""

변수의 범위 지정

statements:
    - context: ret := 3 + 4
    - if:
        match: 2 > 1block:
          - context: ret := 5
          - if:
              match: 3 > 2block:
                - context: ret = 0
    - return: context.ret

그 결과는 7입니다. if.block이 결과는 6행에서 내부에서 재초기화하기 ret 때문입니다. 중첩되는 후속 명령문이 이 변수를 참조합니다. 그러나 규칙 엔진이 if.block을 벗어나면 행 2에서 초기화된 변수에 액세스할 수 있습니다.

추적 로깅 예시

이 예제는 추적 로깅 문을 사용하는 방법을 보여줍니다.

statements:
  - context: uid := user.id
  - context: userEmail := "user@test.com"
  - debug: '"This is an example of a trace log at time " + string(now)'
  - debugx: 
      log: '"The user id obtained: " + context.uid'
      fields:
          flow: '"login"'
          time: 'string(now)'
          userEmail: context.userEmail
  - return: context.uid  + ", " + context.userEmail

"This is an example of a trace log at time <timestamp>"debug 문장의 경우, 제공된 표현식이 평가되어 로 기록됩니다.

"The user id obtained: <user id>"해당 debugx 블록의 경우, 제공된 표현식이 평가되어 로 기록됩니다. 다음 사용자 정의 메타데이터 필드가 로그와 함께 전송됩니다.
"flow" "login"
"time" "<timestamp>"
"userEmail" "user@test.com"

중요 제한사항

  • context 프레임에서 초기화되는 변수는 해당 프레임 내에서 또는 내부 하위 프레임에서만 작동할 수 있습니다. 이전 규칙 예제에서 변수 managerName은 초기화된 if 프레임 밖에서는 액세스할 수 없습니다.
  • elseifselse 프레임은 if 프레임이 동일한 레벨인 경우에만 사용할 수 있습니다.
  • 모든 ifelseifs 프레임에는 항상 부울 값을 리턴하는 match 표현식이 있어야 합니다.
  • 규칙 평가 플로우에 return 명령문이 발생하지 않는 경우 널 값이 리턴됩니다. 오류가 예외 처리되지 않거나 가능한 모든 플로우에 return이 있는지 확인하기 위해 구문 검사가 수행되지 않습니다. 규칙 작성자는 규칙의 모든 플로우에서 허용 가능한 값을 리턴하는지 확인해야 합니다.