Funções definidas pelo usuário do JavaScript no Azure Stream Analytics

O Stream Analytics do Azure dá suporte a funções definidas pelo usuário gravadas em JavaScript. Usando o conjunto rico de métodos String, RegExp, Math, Array e Date que o JavaScript oferece, você pode criar transformações complexas de dados em trabalhos de Stream Analytics. As funções definidas pelo usuário do JavaScript dão suporte a funções escalares sem estado somente para computação que não requerem conectividade externa. O valor retornado de uma função pode ser apenas um valor escalar (único). Depois de adicionar uma função definida pelo usuário do JavaScript a um trabalho, você poderá usar a função em qualquer lugar na consulta, como uma função escalar interna.

Este artigo descreve quando usar funções definidas pelo usuário em JavaScript e como defini-las e chamá-las em seus trabalhos de Análise de Fluxos.

Quando usar uma função definida pelo usuário em JavaScript

Aqui estão alguns cenários nos quais as funções definidas pelo usuário JavaScript podem ser úteis:

  • Análise e manipulação de cadeias usando funções de expressão regular, por exemplo, Regexp_Replace() e Regexp_Extract()
  • Decodificação e codificação de dados, por exemplo, conversão de binário para hexadecimal
  • Realizando cálculos matemáticos usando funções matemáticas em JavaScript
  • Executar operações de matriz como classificar, unir, localizar e preencher

Aqui estão algumas coisas que você não pode fazer usando uma função definida pelo usuário em JavaScript no Stream Analytics:

  • Faça chamadas a endpoints REST externos, por exemplo, para realizar uma busca reversa de IP ou obter dados de referência de uma fonte externa
  • Realizar serialização ou desserialização em formatos personalizados de eventos em entradas ou saídas
  • Criar agregações personalizadas

Embora funções como Date.GetDate() ou Math.random() não estejam bloqueadas na definição de funções, evite usá-las. Essas funções não retornam o mesmo resultado sempre que você as chama e o serviço Azure Stream Analytics não mantém um diário das invocações da função e dos resultados retornados. Se uma função retorna um resultado diferente nos mesmos eventos, a repetibilidade não é garantida quando você ou o serviço de Stream Analytics reiniciam o trabalho.

Defina uma função definida pelo usuário em JavaScript no portal do Azure

Para um trabalho de Stream Analytics que roda na nuvem, adicione uma função definida pelo usuário em JavaScript na página de Funções em Topologia de Trabalhos, onde o menu +Add inclui uma opção UDF em JavaScript .

Observação

Essa experiência se aplica a jobs de Stream Analytics configurados para rodar na nuvem. Se o trabalho do Stream Analytics é configurado para ser executado no Azure IoT Edge, use, em vez disso, o Visual Studio e grave a função definida pelo usuário usando C# .

Captura de tela da página de Funções do portal do Azure mostrando o menu Adicionar com a opção UDF do JavaScript.

Uma definição de função consiste nas seguintes propriedades:

Propriedade Descrição
Alias da função O nome que invoca a função na sua consulta.
Tipo de saída O tipo que a função definida pelo usuário em JavaScript retorna na sua consulta do Stream Analytics.
Definição de função A implementação da sua função JavaScript que roda toda vez que o UDF é invocado a partir da sua consulta.

Teste e solucione problemas na lógica UDF do JavaScript

Como o portal de Stream Analytics não suporta depuração e teste da lógica dessas funções definidas pelo usuário, você pode testar e depurar sua lógica UDF em JavaScript em qualquer navegador. Quando a função funciona como esperado, ela está pronta para ser adicionada ao trabalho do Stream Analytics e ser invocada diretamente na sua consulta. Você também pode testar sua lógica de consulta com um UDF em JavaScript usando as ferramentas Stream Analytics para o Visual Studio.

O Stream Analytics trata erros de tempo de execução do JavaScript como fatais e os expõe por meio do Log de Atividades. O log está disponível no portal do Azure na página de registro de atividades do seu trabalho.

Chamar uma função definida pelo usuário do JavaScript em uma consulta

Para invocar sua função JavaScript em sua consulta, use o alias da função prefixado por udf. O exemplo a seguir mostra um UDF JavaScript que converte valores hexadecimais em inteiros em uma consulta de Stream Analytics.

    SELECT
        time,
        UDF.hex2Int(offset) AS IntOffset
    INTO
        output
    FROM
        InputStream

Objetos JavaScript com suporte

As funções definidas pelo usuário JavaScript do Azure Stream Analytics suportam os objetos JavaScript padrão e integrados. Esses objetos dão às suas funções acesso a operações comuns de string, matemática, array e data sem nenhuma configuração extra. Para uma lista completa dos objetos disponíveis, veja Objetos Globais. Como a linguagem de consulta Stream Analytics e o JavaScript não compartilham o mesmo sistema de tipos, o Stream Analytics converte valores à medida que eles passam entre os dois.

Conversão de tipos no Stream Analytics e no JavaScript

A linguagem de consulta Stream Analytics e JavaScript suportam diferentes tipos. Esta tabela lista os mapeamentos de conversão entre os dois:

Stream Analytics JavaScript
bigint Número (o JavaScript pode representar apenas o inteiro até 2^53 exatamente)
Data e hora Data (o JavaScript dá suporte somente a milissegundos)
duplo Número
nvarchar(MAX) String
Gravar Objeto
Array Array
NULO Nulo

Aqui estão as conversões de JavaScript para Stream Analytics:

JavaScript Stream Analytics
Número Bigint (se o número for arredondado e estiver entre long.MinValue e long.MaxValue; caso contrário, será dobrado)
Data Data e hora
String nvarchar(MAX)
Objeto Registro
Array Array
Nulo, Indefinido NULO
Qualquer outro tipo (por exemplo, uma função ou um erro) Sem suporte (resulta em erro de runtime)

JavaScript diferencia maiúsculas de minúsculas, e o uso de maiúsculas e minúsculas nos campos do objeto no código JavaScript deve corresponder ao uso de maiúsculas e minúsculas dos campos nos dados recebidos. Trabalhos com nível de compatibilidade 1.0 convertem campos da instrução SQL SELECT para minúsculas. No nível de compatibilidade 1.1 e superiores, os campos da instrução SELECT têm a mesma capitalização especificada na consulta SQL.

Padrões de função comuns

Os padrões a seguir mostram maneiras comuns de usar funções definidas pelo usuário em JavaScript para transformar dados em suas consultas de Stream Analytics. Cada padrão inclui uma definição de função e uma consulta de exemplo que a invoca.

Escrever JSON aninhado como saída

Se você tiver uma etapa subsequente de processamento que use a saída de um trabalho do Stream Analytics como entrada, e ela exigir um formato JSON, grave uma cadeia de caracteres JSON na saída. A definição de função a seguir chama a função JSON.stringify() para empacotar todos os pares nome/valor da entrada e então escrevê-los como um único valor de string na saída.

function main(x) {
return JSON.stringify(x);
}

Uma consulta de Análise de Fluxo invoca a função conforme mostrado no exemplo a seguir.

SELECT
    DataString,
    DataValue,
    HexValue,
    UDF.jsonstringify(input) As InputEvent
INTO
    output
FROM
    input PARTITION BY PARTITIONID

Converter uma cadeia de caracteres em um objeto JSON para processamento

Se você tem um campo de string que é JSON e quer convertê-lo em um objeto JSON para processamento em um UDF JavaScript, pode usar a função JSON.parse() para criar um objeto JSON que poderá então usar. A definição de função a seguir analisa a cadeia e retorna uma propriedade do objeto resultante.

function main(x) {
var person = JSON.parse(x);  
return person.name;
}

Uma consulta de Análise de Fluxo invoca a função conforme mostrado no exemplo a seguir.

SELECT
    UDF.getName(input) AS Name
INTO
    output
FROM
    input

Usar try/catch para tratamento de erro

Blocos try/catch podem ajudar a identificar problemas com dados de entrada malformados que você passa para um UDF JavaScript. A seguinte definição de função utiliza um bloco try/catch para lidar com erros de análise sintática.

function main(input, x) {
    var obj = null;

    try{
        obj = JSON.parse(x);
    }catch(error){
        throw input;
    }
    
    return obj.Value;
}

Na consulta de exemplo a seguir, você passa o registro inteiro como primeiro parâmetro para que a função possa retorná-lo caso haja um erro.

SELECT
    A.context.company AS Company,
    udf.getValue(A, A.context.value) as Value
INTO
    output
FROM
    input A

toLocaleString()

O método toLocaleString em JavaScript retorna uma string sensível à linguagem que representa os dados de data-hora de onde você chama o método. Embora o Azure Stream Analytics aceite apenas data-hora UTC como carimbo de tempo do sistema, você pode usar esse método para converter o carimbo de tempo do sistema para outro local e fuso horário. Esse método segue o mesmo comportamento de implementação do disponível no Internet Explorer. A definição de função a seguir converte a data e hora de entrada para a localidade de-DE.

function main(datetime){
    const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
    return datetime.toLocaleDateString('de-DE', options);
}

Na consulta de exemplo a seguir, um valor de data e hora é passado como valor de entrada.

SELECT
    udf.toLocaleString(input.datetime) as localeString
INTO
    output
FROM
    input

A saída desta consulta é a data e hora de entrada em de-DE, com as opções fornecidas.

Samstag, 28. December 2019

Log de usuário

Logging é o mecanismo que o Azure Stream Analytics utiliza para capturar informações personalizadas de uma função JavaScript definida pelo usuário enquanto um trabalho está em execução. Como, fora isso, um job em execução é opaco, os logs oferecem visibilidade, em tempo real, do comportamento e de se o seu código personalizado está funcionando corretamente. Cada mensagem de log carrega um nível de evento que indica quão significativa é a mensagem e se o trabalho pode continuar rodando.

Mensagens informativas vêm do método console.info(), como console.info('my info message');. Esse nível registra informações gerais durante a execução e não interrompe o cálculo. Mensagens de aviso vêm do método console.warn( ), como console.warn('my warning message');. Esse nível registra dados que podem ser inesperados, mas ainda aceitáveis para computação, então o trabalho continua sendo executado. Mensagens de erro vêm dos métodos console.error() e console.log(), como console.error('my error message');. Esses métodos se aplicam apenas a casos em que o código não pode continuar, então eles lançam uma exceção com a informação de erro fornecida e interrompem o trabalho.

Você pode acessar mensagens de log por meio de logs de diagnóstico.

atob() e btoa()

O Stream Analytics suporta dois métodos para conversão em Base64, que é uma forma comum de codificar dados binários como texto. O método btoa() codifica uma string ASCII em Base64, e o método atob() decodifica uma string de dados codificados em Base64 de volta para uma string ASCII. No exemplo a seguir, btoa() codifica uma string ASCII e atob() então decodifica o resultado de volta para a string original.

var myAsciiString = 'ascii string';
var encodedString = btoa(myAsciiString);
var decodedString = atob(encodedString);