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

O Azure Stream Analytics suporta as funções definidas pelo utilizador escritas no JavaScript. Ao usar o conjunto rico de métodos String, RegExp, Math, Array e Date que o JavaScript fornece, pode criar transformações complexas de dados em trabalhos de Stream Analytics. As funções JavaScript definidas pelo utilizador suportam funções escalares sem estado, apenas de computação, que não exigem conectividade externa. O valor devolvido de uma função só pode ser um valor escalar (único). Depois de adicionar uma função definida pelo utilizador do JavaScript para uma tarefa, pode utilizar a função em qualquer parte da consulta, como uma função escalar incorporada.

Este artigo descreve quando usar funções definidas pelo utilizador em JavaScript e como as definir e chamar nos seus trabalhos de Análise de Fluxos.

Quando usar uma função definida pelo utilizador em JavaScript

Seguem-se alguns cenários onde as funções definidas pelo utilizador do JavaScript poderão ser úteis:

  • Analisar e manipular cadeias usando funções de expressão regular, por exemplo, Regexp_Replace() e Regexp_Extract()
  • Descodificar e codificar dados, por exemplo, conversão de binário para hexadecimal
  • Fazer cálculos matemáticos usando funções matemáticas em JavaScript
  • Realizar operações de array como classificar, juntar, localizar e preencher

Aqui estão algumas coisas que não podes fazer usando uma função definida pelo utilizador em JavaScript no Stream Analytics:

  • Chamar endpoints REST externos, por exemplo, para efetuar uma pesquisa inversa de IP ou obter dados de referência de uma fonte externa
  • Realizar serialização ou desserialização de formatos de eventos personalizados 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 toda vez que você as chama, e o serviço Azure Stream Analytics não mantém um diário de invocações de função e resultados retornados. Se uma função devolver um resultado diferente nos mesmos eventos, a repetibilidade não é garantida quando você ou o serviço Stream Analytics reiniciam o trabalho.

Defina uma função JavaScript definida pelo utilizador no portal Azure

Para um trabalho de Stream Analytics que corra na cloud, adicione uma função definida pelo utilizador em JavaScript a partir da página de Funções em Topologia de Trabalhos, onde o menu +Add inclui uma opção UDF em JavaScript .

Nota

Esta experiência aplica-se a trabalhos de Stream Analytics configurados para correr na cloud. Se seu trabalho do Stream Analytics estiver configurado para ser executado no Azure IoT Edge, use o Visual Studio e escreva a função definida pelo usuário usando C#.

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

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

Propriedade Descrição
Alias de função O nome que invoca a função na tua consulta.
Tipo de saída O tipo que a função JavaScript definida pelo utilizador devolve à sua consulta de Stream Analytics.
Definição de função A implementação da sua função JavaScript que é executada sempre que o UDF é invocado a partir da sua consulta.

Teste e resolução de problemas da lógica UDF em JavaScript

Como o portal Stream Analytics não suporta a depuração e o teste da lógica destas funções definidas pelo utilizador, pode testar e depurar a lógica do seu JavaScript UDF em qualquer navegador. Quando a função funcionar como esperado, estará pronta para ser adicionada à tarefa do Stream Analytics e chamada diretamente na sua consulta. Também pode testar a sua lógica de consulta com um UDF JavaScript usando as ferramentas Stream Analytics para o Visual Studio.

O Stream Analytics trata erros de execução em JavaScript como fatais e revela-os através do registo de atividade. O registo está disponível no portal Azure na página do registo de atividades do seu trabalho.

Chamar uma função definida pelo utilizador do JavaScript numa consulta

Para invocar a sua função JavaScript na consulta, utilize o alias da função precedido de udf. O exemplo seguinte mostra um UDF JavaScript que converte valores hexadecimais para um inteiro numa consulta de Stream Analytics.

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

Objetos de JavaScript suportados

As funções definidas pelo utilizador JavaScript do Azure Stream Analytics suportam os objetos JavaScript padrão e incorporados. Estes objetos dão às tuas funções acesso a operações comuns de string, matemática, array e data sem qualquer configuração adicional. Para uma lista completa dos objetos disponíveis, consulte Objetos Globais. Como a linguagem de consulta Stream Analytics e o JavaScript não partilham o mesmo sistema de tipos, o Stream Analytics converte os valores à medida que passam entre os dois.

Conversão de tipos do Stream Analytics e do JavaScript

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

Stream Analytics JavaScript
bigint Number (o JavaScript só pode representar números inteiros até precisamente 2^53)
DateTime Date (o JavaScript só suporta milissegundos)
duplo Número
nvarchar(MAX) String
Registo Objeto
Matriz Matriz
NULL Nulo

Seguem-se conversões do JavaScript para o Stream Analytics:

JavaScript Stream Analytics
Número Bigint (se o número for redondo e entre long.MinValue e long.MaxValue; caso contrário, é duplo)
Date DateTime
String nvarchar(MAX)
Objeto Registo
Matriz Matriz
Nulo, Indefinido NULL
Qualquer outro tipo (por exemplo, uma função ou erro) Não é suportado (resulta em erro em tempo de execução)

O JavaScript faz distinção entre maiúsculas e minúsculas, e a utilização de maiúsculas e minúsculas nos campos do objeto no código JavaScript deve corresponder à dos campos nos dados de entrada. 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ções comuns

Os padrões seguintes mostram formas comuns de usar funções definidas pelo utilizador em JavaScript para transformar dados nas suas consultas de Stream Analytics. Cada padrão inclui uma definição de função e uma consulta de exemplo que a invoca.

Gravar JSON aninhado na saída

Se tiver um passo de processamento de seguimento que utiliza uma saída da tarefa do Stream Analytics como entrada e requer um formato JSON, pode escrever uma cadeia JSON para a saída. A seguinte definição de função chama a função JSON.stringify() para empacotar todos os pares nome/valor da entrada e depois escrevê-los como um único valor de cadeia na saída.

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

Uma consulta de Stream Analytics invoca a função como mostrado no exemplo seguinte.

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

Transmitir cadeia de caracteres para objeto JSON para processar

Se tiveres um campo de string que é JSON e quiseres convertê-lo para objeto JSON para processamento num UDF JavaScript, podes usar a função JSON.parse() para criar um objeto JSON que depois possas usar. A seguinte definição de função analisa a cadeia e devolve uma propriedade do objeto resultante.

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

Uma consulta de Stream Analytics invoca a função como mostrado no exemplo seguinte.

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

Utilize try/catch para o tratamento de erros

Os blocos try/catch podem ajudá-lo a identificar problemas com dados de entrada malformados que transmite a uma UDF em 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 seguinte, passa o registo inteiro como primeiro parâmetro para que a função possa devolvê-lo se houver 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 devolve uma string sensível à linguagem que representa os dados data-hora de onde chamas o método. Embora o Azure Stream Analytics aceite apenas data-hora UTC como carimbo temporal do sistema, pode usar este método para converter o carimbo temporal do sistema para outro local e fuso horário. Este método segue o mesmo comportamento de implementação do disponível no Internet Explorer. A definição de função seguinte converte a data e hora de entrada para a configuração regional 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 seguinte, é passada uma data-hora como valor de entrada.

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

O resultado desta consulta é a data e hora de entrada em de-DE, com as opções fornecidas.

Samstag, 28. December 2019

Registo de utilizadores

O logging é o mecanismo que o Azure Stream Analytics utiliza para captar informação personalizada de uma função definida pelo utilizador em JavaScript enquanto um job está a correr. Como um trabalho em execução é, de resto, opaco, os dados de registo dão-lhe visibilidade sobre o comportamento e a correção do seu código personalizado em tempo real. Cada mensagem de registo transporta um nível de evento que indica a importância da mensagem e se o trabalho pode continuar a correr.

As mensagens informativas provêm do método console.info(), como console.info('my info message');. Este nível regista informação geral durante a execução e não interrompe o cálculo. As mensagens de aviso vêm do método console.warn(), como console.warn('my warning message');. Este nível regista dados que podem ser inesperados, mas que ainda assim são aceitáveis para computação, pelo que o trabalho continua a ser executado. As mensagens de erro vêm dos métodos console.error() e console.log(), como console.error('my error message');. Estes métodos aplicam-se apenas a casos em que o código não pode continuar, por isso lançam uma exceção com a informação de erro fornecida e param o trabalho.

Pode aceder às mensagens de registo através dos registos 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 cadeia ASCII em Base64, e o método atob() decodifica uma cadeia de dados codificados em Base64 para uma cadeia ASCII. No exemplo seguinte, btoa() codifica uma cadeia ASCII e atob() depois decodifica o resultado de volta para a cadeia original.

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