Executor de regra multilinhas
Há situações em que é necessário construir regras multilinhas para calcular um valor desejado para um atributo. IBM® Verify permite configurar tanto regras simples de uma linha quanto regras mais avançadas de várias linhas.
Para regras de sintaxe de linha única, consulte Funções de atributos.
Elementos de uma regra multilinhas
A regra multilinhas é escrita no formato YAML. Ela é restrita de acordo com as necessidades de formatação de um documento YAML. O analisador YAML utilizado suporta a maior parte do conteúdo de YAML 1.1 e 1.2.
- Instrução
- Uma instrução é o bloco de construção da regra e pode ser de diferentes tipos. Por exemplo, a instrução de retorno calcula a expressão que foi fornecida e retorna a expressão como o valor de regra.
- Bloco
- Um bloco é uma coleção limitada de instruções. A regra começa com um bloco de nível superior chamado
statements. Os blocos podem existir dentro de certos tipos de instrução. Por exemplo,if.blocké a coleção de instruções a serem executadas quando a instruçãoif.matchcorrespondente for avaliada como true. - Contexto do bloco
- Um contexto de bloco é uma coleção de variáveis que estão disponíveis dentro desse bloco. Os sub-blocos podem acessar o contexto dos blocos pais. Blocos pais não podem acessar o contexto de sub-blocos.
- Expressão
- Uma expressão é um fragmento que usa a mesma sintaxe das expressões de linha única. Consulte Funções de atributos.
Tipos de instrução suportados
- Contexto
- Retornar
- Se
Instrução de contexto
context é usada para inicializar e designar valores a variáveis nomeadas. Ela suporta dois operadores.:=- Este operador é usado para inicializar uma nova variável dentro do bloco de contexto no qual a instrução é avaliada. Por exemplo, se uma variável for inicializada dentro de um
if.block, ela não ficará disponível fora desse bloco nas instruções subsequentes.
=- Este operador é usado para atribuir um valor a uma variável existente. A variável pode existir no bloco de contexto atual ou em um bloco pai.
context: {{varname}} := {{expression}}. O uso é context.{{varname}} para acessar {{varname}} em instruções subsequentes no mesmo bloco ou sub-blocos.Instrução Return
A instrução de retorno é usada para indicar ao mecanismo de regras que finalize a execução e retorne imediatamente o valor que foi calculado.
O formato é return: {{expression}}.
Instrução Se
A instrução if é usada para a construção de blocos condicionais. Ela é composta por várias propriedades, ao contrário das duas instruções anteriores.
| Nome | Descrição | Formato |
|---|---|---|
match |
Se essa condição for avaliada como true, o block correspondente será
executado. |
match: 1 == 2 |
block |
Um bloco limitado de instruções que devem ser executadas se match for avaliada como true. |
Uma matriz YAML de instruções padrão |
elsifs |
Matriz de condições else-if que são avaliadas caso match não seja avaliada como true. |
Matrizes YAML que são instruções if aninhadas |
else |
Bloco de instruções que são executadas caso o resultado da avaliação não seja true para match e nem para qualquer tipo de elseifs.match. |
Uma matriz YAML de instruções |
Criação de logs de rastreio
É possível adicionar o registro de rastreamento a uma regra de várias linhas para enviar registros de depuração. As propriedades de registro de rastreamento são aplicadas se uma regra for executada com o modo de rastreamento ativado. O registro de rastreamento é suportado pelas debug propriedades e debugx .
debugdeclaraçãoA
debuginstrução é usada para indicar a execução da expressão fornecida e registrar o valor retornado. A expressão deve sempre resultar em uma sequência de caracteres.Formato -
debug: {{expression}}
debugxbloqueioO
debugxbloco é composto por duas propriedades:logefields.Nome Descrição Formato log A expressão fornecida é avaliada e o valor retornado é registrado. A expressão deve sempre resultar em uma sequência de caracteres. log: {{expression}}Campos Campos de metadados personalizados que são enviados junto com o log. Fornecido na forma de um mapa de pares chave-valor. O valor de cada par é uma expressão que deve resultar em uma sequência de caracteres. {{field_key}}: {{expression}}Consulte a seção para ver um exemplo de função que ilustra o registro de rastreamento.
Fragmentos
Esta lista de trechos não é completa e não abrange todos os usos possíveis de regras. No entanto, essa lista fornece algumas amostras que podem ser usadas no estado em que se encontram ou podem ser ampliadas.
Obter o nome de exibição do gerente
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")
Transformar o domínio de e-mail
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: ""
Definição de escopo de variáveis
statements:
- context: ret := 3 + 4
- if:
match: 2 > 1block:
- context: ret := 5
- if:
match: 3 > 2block:
- context: ret = 0
- return: context.ret
O resultado é 7. Esse resultado é porque a linha 6 reinicializa ret dentro do if.block. As instruções aninhadas subsequentes veem essa variável. No entanto, depois que o
mecanismo de regra sai do if.block, ele pode acessar a variável que foi inicializada na
linha 2.
Exemplo de registro de rastreamento
Este exemplo ilustra como usar instruções de registro de rastreamento.
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
Para a debug instrução, a expressão fornecida será avaliada e registrada como "This is an example of a trace log at time <timestamp>".
debugx bloco, a expressão fornecida será avaliada e registrada como "The user id obtained: <user id>". Os seguintes campos de metadados personalizados serão enviados junto com o log.| Chave | Valor |
|---|---|
"flow" |
"login" |
"time" |
"<timestamp>" |
"userEmail" |
"user@test.com" |
Restrições importantes
- As variáveis que são inicializadas pelo quadro
contextpodem viver apenas dentro desse quadro ou de subquadros dentro dele. No exemplo de regra anterior, a variávelmanagerNamenão fica acessível fora do quadroifno qual ela foi inicializada. - Os quadros
elseifseelsepoderão ser usados apenas se um quadroifestiver no mesmo nível. - Todos os quadros
ifeelseifsdevem ter uma expressãomatchque sempre retorne um valor Booleano. - Se o fluxo de avaliação de regra não encontrar uma instrução
return, um valor nulo será retornado. Nenhum erro é lançado nem a verificação de sintaxe é executada para certificar-se de que todos os fluxos possíveis tenham umreturn. O autor da regra deve assegurar que todos os fluxos da regra retornem um valor aceitável.