複数行ルール実行プログラム
属性に必要な値を計算するために、複数行ルールを作成する必要が生じることがよくあります。 IBM® Verify には、単純な単一行ルールとより高度な複数行ルールの両方を構成する機能が用意されています。
単一行構文規則については、 属性関数を参照してください。
複数行ルールの要素
複数行ルールは YAML 形式で記述されます。 これは、YAML 文書のフォーマット設定の要件によって制約されます。 使用される YAML パーサーは、YAML 1.1 および 1.2 の大部分をサポートします。
- ステートメント
- ステートメントはルールのビルディング・ブロックであり、各種タイプのステートメントが存在します。 例えば、return ステートメントは、提供された式を計算し、ルール値として式を返します。
- ブロック
- ブロックは、複数のステートメントから成る限定されたコレクションです。 ルールは、
statementsと呼ばれる最上位ブロックから開始されます。 ブロックは、特定のステートメント・タイプの内部に存在できます。 例えば、if.blockは、対応するif.matchステートメントが true と評価された場合に実行される、複数のステートメントから成るコレクションです。 - ブロック・コンテキスト
- ブロック・コンテキストは、そのブロック内で使用できる変数のコレクションです。 サブブロックは、親ブロックのコンテキストにアクセスできます。 親ブロックは、サブブロックのコンテキストにアクセスできません。
- 式
- 式は、単一行の式と同じ構文を使用するスニペットです。 属性関数を参照してください。
サポートされるステートメント・タイプ
- コンテキスト
- Return
- If
context ステートメント
context ステートメントは、値を初期化し、名前付き変数に割り当てるために使用されます。 これは 2 つの演算子をサポートします。:=- この演算子は、ステートメントが評価されるコンテキスト・ブロック内で新規変数を初期化するために使用されます。 例えば、変数が
if.block内で初期化された場合、その変数は以降のステートメントでこのブロックの外部では使用できません。
=- この演算子は、値を既存の変数に割り当てるために使用されます。 変数は、現在のコンテキスト・ブロック内または親ブロック内に存在できます。
context: {{varname}} := {{expression}} です。 使用法: context.{{varname}} は、以降のステートメントで同じブロック内またはサブブロック内の {{varname}} にアクセスします。return ステートメント
return ステートメントは、実行を終了し、計算された値を即時に返すように、ルール・エンジンに指示するために使用されます。
形式は return: {{expression}} です。
if ステートメント
if ステートメントは、条件付きブロックを作成するために使用されます。 このステートメントは、前の 2 つのステートメントとは異なり、いくつかのプロパティーから成り立っています。
| 名前 | 説明 | フォーマット |
|---|---|---|
match |
この条件が true と評価された場合は、対応する block が実行されます。 |
match: 1 == 2 |
block |
match が true と評価された場合に実行される必要がある、複数のステートメントから成る限定されたブロック。 |
ステートメントの標準 YAML 配列 |
elsifs |
match が true と評価されなかった場合に評価される、else-if 条件の配列。 |
ネストされた if ステートメントである YAML 配列 |
else |
match およびすべての elseifs.match が true と評価されなかった場合に実行される、複数のステートメントから成るブロック。 |
ステートメントの YAML 配列 |
トレース・ロギング
デバッグ・ログを送信するために、トレース・ロギングを複数行ルールに追加できます。 トレース・ロギング・プロパティーは、有効なトレース・モードでルールが実行された場合に実行されます。 トレース・ロギングは、 debug プロパティーおよび debugx プロパティーによってサポートされます。
debug記述debugステートメントは、指定された式を実行し、返された値をログに記録することを示すために使用されます。 式は常にストリングに評価される必要があります。フォーマット-
debug: {{expression}}
debugxブロックdebugxブロックは、logとfieldsの 2 つのプロパティーで構成されています。名前 説明 フォーマット ログ 指定された式が評価され、返された値がログに記録されます。 式は常にストリングに評価される必要があります。 log: {{expression}}フィールド ログとともに送信されるカスタム・メタデータ・フィールド。 キーと値のペアのマップとして提供されます。 各ペアの値は式であり、ストリングに評価される必要があります。 {{field_key}}: {{expression}}トレース・ロギングを示すサンプル関数については、 セクション を参照してください。
スニペット
以下のスニペットのリストは、包括的ではなく、ルールのすべての可能な使用法を示しているわけではありません。 しかし、このリストで提供されるいくつかのサンプルは、そのまま使用するか、拡張して使用することができます。
マネージャーの表示名の取得
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")
E メール・ドメインの変換
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 です。 この結果は、6 行目で if.block内の 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
debug ステートメントの場合、指定された式は評価され、 "This is an example of a trace log at time <timestamp>"としてログに記録されます。
debugx ブロックの場合、指定された式は評価され、 "The user id obtained: <user id>"としてログに記録されます。 以下のカスタム・メタデータ・フィールドがログとともに送信されます。| キー | 値 |
|---|---|
"flow" |
"login" |
"time" |
"<timestamp>" |
"userEmail" |
"user@test.com" |
重要な制限事項
contextフレームで初期化された変数は、そのフレームおよびそのサブフレーム内でのみ存続します。 前出のルール例の場合、変数managerNameは、その変数を初期化したifフレームの外部からはアクセスできません。elseifsフレームおよびelseフレームは、ifフレームが同じレベルにある場合にのみ使用できます。ifフレームおよびelseifsフレームはすべて、常にブール値を返すmatch式が必要です。- ルール評価フローに
returnステートメントがない場合は、ヌル値が返されます。 エラーはスローされず、想定し得るすべてのフローにreturnがあることを確認するための構文検査も実行されません。 ルールの作成者は、ルールのすべてのフローが許容可能値を返すことを確認する必要があります。