Exercício – adicionar lógica à aplicação de funções

Concluído

Vamos continuar com o nosso exemplo de unidade de engrenagem e adicionar a lógica ao serviço de temperatura. Especificamente, vamos receber dados de um pedido HTTP.

Requisitos da função

Primeiro, precisamos de definir alguns requisitos para a nossa lógica:

  • Temperaturas de 0 a 25 graus devem ser sinalizadas como OK.
  • Temperaturas acima de 25 até 50 graus devem ser sinalizadas como CUIDADO.
  • As temperaturas acima de 50 graus devem ser sinalizadas como PERIGO.

Adicionar uma função à sua aplicação de funções

Conforme descrito na unidade anterior, o Azure fornece modelos que ajudam você a criar funções. Nesta unidade, você usa o HttpTrigger modelo para implementar o serviço de temperatura.

  1. No exercício anterior, você implantou seu aplicativo de função e o abriu. Se ainda não estiver aberto, pode abri-lo a partir da página inicial selecionando Todos os recursos e, em seguida, selecionando a sua aplicação de funções, denominada algo como escada rolante-functions-xxx.

  2. Na tela Aplicativo de Função, na guia Funções , selecione Criar no portal do Azure. O painel de funções Criar é exibido.

  3. Em Selecione um modelo, selecione Gatilho HTTP e selecione Avançar.

  1. Deixe o nome da função como HttpTrigger1 e o nível de autorização como função e selecione Criar. A função HttpTrigger1 é criada e exibida no painel Função HttpTrigger1 .

  2. Selecione a guia Código + Teste . O editor de código é aberto, exibindo o conteúdo do arquivo de código index.js para sua função. O código padrão que o modelo HTTP gerou aparece no trecho a seguir.

    module.exports = async function (context, req) {
        context.log('JavaScript HTTP trigger function processed a request.');
    
        const name = (req.query.name || (req.body && req.body.name));
        const responseMessage = name
            ? "Hello, " + name + ". This HTTP triggered function executed successfully."
            : "This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response.";
    
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: responseMessage
        };
    }
    

    Sua função espera que um nome seja passado por meio da cadeia de caracteres de consulta de solicitação HTTP ou como parte do corpo da solicitação. A função responde retornando a mensagem Olá, <nome>. Essa função acionada por HTTP foi executada com êxito., ecoando de volta o nome que foi enviado na solicitação.

    Na lista suspensa do arquivo de origem, selecione function.json para visualizar a configuração da função, que deve se parecer com o código a seguir.

    {
      "bindings": [
        {
          "authLevel": "function",
          "type": "httpTrigger",
          "direction": "in",
          "name": "req",
          "methods": [
            "get",
            "post"
          ]
        },
        {
          "type": "http",
          "direction": "out",
          "name": "res"
        }
      ]
    }
    

    Esse arquivo de configuração declara que a função é executada quando recebe uma solicitação HTTP. A associação de saída declara que a resposta é enviada como uma resposta HTTP.

  1. Na secção Detalhes do modelo, no campo Nova Função, introduza DriveGearTemperatureService. Deixe o nível de Autorização como Função e selecione Criar para criar a função. O painel Visão geral da função DriveGearTemperatureService é exibido.

  2. No menu Função, selecione Código + Teste. O editor de código é aberto com o conteúdo do arquivo de código run.ps1 . O código predefinido gerado pelo modelo é apresentado no seguinte fragmento.

    using namespace System.Net
    
    # Input bindings are passed in via param block.
    param($Request, $TriggerMetadata)
    
    # Write to the Azure Functions log stream.
    Write-Host "PowerShell HTTP trigger function processed a request."
    
    # Interact with query parameters or the body of the request.
    $name = $Request.Query.Name
    if (-not $name) {
        $name = $Request.Body.Name
    }
    
    $body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
    
    if ($name) {
        $body = "Hello, $name. This HTTP triggered function executed successfully."
    }
    
    # Associate values to output bindings by calling 'Push-OutputBinding'.
    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
        StatusCode = [HttpStatusCode]::OK
        Body = $body
    })
    

    A nossa função espera que seja transmitido um nome através da cadeia de consulta do pedido HTTP ou como parte do corpo do pedido. As funções HTTP têm de gerar uma resposta ao escrever no respetivo enlace de saída, o que é feito nas Funções do PowerShell, com o cmdlet Push-OutputBinding. Esta função retorna a mensagem Olá, $name, ecoando de volta o nome que foi enviado na solicitação.

  3. Na lista suspensa de origem, selecione function.json para visualizar a configuração da função, que deve ser semelhante à seguinte.

    {
      "bindings": [
        {
          "authLevel": "function",
          "type": "httpTrigger",
          "direction": "in",
          "name": "Request",
          "methods": [
            "get",
            "post"
          ]
        },
        {
          "type": "http",
          "direction": "out",
          "name": "Response"
        }
      ]
    }
    

    Esta configuração declara que a função é executada quando recebe um pedido HTTP. A associação de saída declara que a resposta é enviada como uma resposta HTTP.

Testar a função

Gorjeta

O cURL é uma ferramenta de linha de comandos que pode ser utilizada para enviar ou receber ficheiros. Está incluído no Linux, macOS e Windows 10, e pode ser transferido para a maioria dos outros sistemas operativos. O cURL suporta vários protocolos, como HTTP, HTTPS, FTP, FTPS, SFTP, LDAP, TELNET, SMTP, POP3, entre outros. Para obter mais informações, veja as seguintes ligações:

Para testar a função, pode enviar um pedido HTTP para o URL da função com o cURL na linha de comandos.

  1. Expanda o quadro Logs na parte inferior do painel de funções de gatilho. Selecione Logs do sistema de arquivos na lista suspensa na parte superior do quadro Logs. O quadro de log deve começar a acumular notificações de rastreamento a cada minuto.

  2. Para encontrar o URL do ponto de extremidade da função, na barra de comandos, selecione Obter URL da função, conforme mostrado na imagem a seguir. Guarde esta ligação ao selecionar Copiar para a área de transferência no final do URL. Armazene este link no Bloco de Notas ou em um aplicativo semelhante para uso posterior.

    Captura de ecrã do portal do Azure que mostra o editor de funções, com o botão Obter URL de função realçado.

  3. Abra um prompt de comando e execute cURL para enviar uma solicitação HTTP para a URL da função. Lembre-se de usar o URL copiado na etapa anterior.

    curl "<your-https-url>"
    

    Gorjeta

    Talvez seja necessário envolver o URL entre aspas para evitar problemas com caracteres especiais no URL.
    Se você estiver no Windows, execute cURL no prompt de comando. O PowerShell tem um comando curl , mas é um alias para Invoke-WebRequest, que não é o mesmo cURLque .

    A resposta deve ter a seguinte aparência.

    This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response.
    

    Agora passe um nome na solicitação. Para fazer isso, você precisa adicionar um parâmetro de cadeia de caracteres de consulta nomeado name para a URL. O exemplo a seguir adiciona o parâmetro name=Azurequery string.

    curl "<your-https-url>&name=Azure"
    

    A resposta deve ter a seguinte aparência.

    Hello, Azure. This HTTP triggered function executed successfully.
    

    A função foi executada com êxito e retornou o nome que você passou na solicitação.

Proteger os acionadores HTTP

Os gatilhos HTTP permitem que você use chaves de API para bloquear chamadores desconhecidos, exigindo uma chave como parte da solicitação. Ao criar uma função, selecione o nível de autorização. Por padrão, o nível é definido como Function, que requer uma chave de API específica da função. Ele também pode ser definido como Admin para usar uma chave "mestre" global ou Anonymous para indicar que nenhuma chave é necessária. Também pode alterar o nível de autorização nas propriedades de função após a criação.

Como você especificou Function quando criou essa função, você precisa fornecer a chave ao enviar a solicitação HTTP. Você pode enviá-lo como um parâmetro de cadeia de caracteres de consulta chamado code. Ou, use o método preferido e passá-lo como um cabeçalho HTTP chamado x-functions-key.

  1. Para encontrar as teclas de função, abra o menu Código + Teste selecionando o nome da sua função (por exemplo, HttpTriger1) na guia Funções no menu Visão geral . Em seguida, selecione a guia Teclas de função .

  2. Por padrão, o valor da chave de função está oculto. Mostrar o valor da chave de função padrão selecionando Mostrar valor. Copie o conteúdo do campo Valor para a área de transferência e armazene essa chave no Bloco de Notas ou em um aplicativo semelhante para uso posterior.

    Captura de ecrã a mostrar o painel Teclas de Função com a tecla de função revelada realçada.

  3. Para testar a função com a tecla de função, abra um prompt de comando e execute cURL para enviar uma solicitação HTTP para a URL da função. Substitua <your-function-key> pelo valor da chave de função que você salvou e substitua <your-https-url> pelo URL da sua função.

    curl --header "Content-Type: application/json" --header "x-functions-key: <your-function-key>" --request POST --data "{\"name\": \"Azure Function\"}" <your-https-url>
    
  4. Revise o comando cURL e verifique se ele tem os seguintes valores:

    • Adicionou um valor de cabeçalho Content-Type do tipo application/json.
    • Passou a Tecla de Função como o valor do cabeçalho x-functions-key.
    • Utilizou um pedido POST.
    • Passou a Função do Azure com a URL da sua função.
  5. Verifique os registos.

    O painel Código + Teste deve abrir uma sessão exibindo a saída do arquivo de log (verifique se Logs do sistema de arquivos está selecionado na lista suspensa na parte superior do painel Logs ). O arquivo de log é atualizado com o status da sua solicitação, que deve ter esta aparência:

```output
2022-02-16T22:34:10.473 [Information] Executing 'Functions.HttpTrigger1' (Reason='This function was programmatically called via the host APIs.', Id=4f503b35-b944-455e-ba02-5205f9e8b47a)
2022-02-16T22:34:10.539 [Information] JavaScript HTTP trigger function processed a request.
2022-02-16T22:34:10.562 [Information] Executed 'Functions.HttpTrigger1' (Succeeded, Id=4f503b35-b944-455e-ba02-5205f9e8b47a, Duration=114ms)
```
```output
2022-02-16T21:07:11.340 [Information] INFORMATION: PowerShell HTTP trigger function processed a request.
2022-02-16T21:07:11.449 [Information] Executed 'Functions.DriveGearTemperatureService' (Succeeded, Id=25e2edc3-542f-4629-a152-cf9ed99680d8, Duration=1164ms)
```

Adicionar lógica de negócio à função

Vamos adicionar a lógica à função, para verificar as leituras de temperatura que ela recebe, e definir um status para cada leitura de temperatura.

A nossa função espera uma matriz de leituras de temperatura. O trecho JSON a seguir é um exemplo do corpo da solicitação que enviamos para nossa função. O nome da matriz pode ser ligeiramente diferente para JavaScript ou PowerShell, mas cada entrada na matriz tem uma ID, carimbo de data/hora e temperatura.

{
    "Readings": [
        {
            "driveGearId": 1,
            "timestamp": 1534263995,
            "temperature": 23
        },
        {
            "driveGearId": 3,
            "timestamp": 1534264048,
            "temperature": 45
        },
        {
            "driveGearId": 18,
            "timestamp": 1534264050,
            "temperature": 55
        }
    ]
}

Vamos substituir o código padrão em nossa função pelo código a seguir que implementa nossa lógica de negócios.

No painel de funções HttpTrigger1 , abra o arquivo index.js e substitua-o pelo código a seguir. Depois de fazer essa alteração, na barra de comandos, selecione Salvar para salvar as atualizações no arquivo.

module.exports = function (context, req) {
    context.log('Drive Gear Temperature Service triggered');
    if (req.body && req.body.readings) {
        req.body.readings.forEach(function(reading) {

            if(reading.temperature<=25) {
                reading.status = 'OK';
            } else if (reading.temperature<=50) {
                reading.status = 'CAUTION';
            } else {
                reading.status = 'DANGER'
            }
            context.log('Reading is ' + reading.status);
        });

        context.res = {
            // status: 200, /* Defaults to 200 */
            body: {
                "readings": req.body.readings
            }
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please send an array of readings in the request body"
        };
    }
    context.done();
};

A lógica que adicionámos é simples. Iteramos através da matriz e definimos o status como OK, CAUTION ou DANGER com base no valor do campo de temperatura. Em seguida, voltamos a enviar a matriz de leituras com um campo de estado adicionado a cada entrada.

Observe as Log instruções quando você expande Logs na parte inferior do painel. Quando a função é executada, essas instruções adicionam mensagens na janela Logs.

Testar a lógica de negócio

Vamos usar o recurso Test/Run no Developer>Code + Test para testar nossa função.

  1. Na guia Código + Teste, selecione Testar/Executar. Na guia Entrada, substitua o conteúdo da caixa de texto Corpo pelo código a seguir para criar nossa solicitação de exemplo.

    {
        "readings": [
            {
                "driveGearId": 1,
                "timestamp": 1534263995,
                "temperature": 23
            },
            {
                "driveGearId": 3,
                "timestamp": 1534264048,
                "temperature": 45
            },
            {
                "driveGearId": 18,
                "timestamp": 1534264050,
                "temperature": 55
            }
        ]
    }
    

Abra o ficheiro run.ps1 e substitua os conteúdos pelo seguinte código. Depois de fazer essa alteração, na barra de comandos, selecione Salvar para salvar as atualizações no arquivo.

using namespace System.Net

param($Request, $TriggerMetadata)

Write-Host "Drive Gear Temperature Service triggered"

$readings = $Request.Body.Readings
if ($readings) {
    foreach ($reading in $readings) {
        if ($reading.temperature -le 25) {
            $reading.Status = "OK"
        }
        elseif ($reading.temperature -le 50) {
            $reading.Status = "CAUTION"
        }
        else {
            $reading.Status = "DANGER"
        }

        Write-Host "Reading is $($reading.Status)"
    }

    $status = [HttpStatusCode]::OK
    $body = $readings
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please send an array of readings in the request body"
}

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

A lógica que adicionámos é simples. Iteramos através da matriz e definimos o status como OK, CAUTION ou DANGER com base no valor do campo de temperatura. Em seguida, voltamos a enviar a matriz de leituras com um campo de estado adicionado a cada entrada.

Repare nas chamadas ao cmdlet Write-Host. Quando a função é executada, essas instruções adicionam mensagens na janela Logs.

Testar a lógica de negócios

Vamos usar o recurso Test/Run no Developer>Code + Test para testar nossa função.

  1. Na guia Código + Teste, selecione Testar/Executar. Na guia Entrada, substitua o conteúdo da caixa de texto Corpo pelo código a seguir para criar nossa solicitação de exemplo.

    {
        "Readings": [
            {
                "driveGearId": 1,
                "timestamp": 1534263995,
                "temperature": 23
            },
            {
                "driveGearId": 3,
                "timestamp": 1534264048,
                "temperature": 45
            },
            {
                "driveGearId": 18,
                "timestamp": 1534264050,
                "temperature": 55
            }
        ]
    }
    
  1. Selecione Executar. A guia Saída exibe o código de resposta HTTP e o conteúdo. Para ver mensagens de log, abra a guia Logs no submenu inferior do painel (se ainda não estiver aberto). A imagem seguinte mostra uma resposta de exemplo no painel de resultados e mensagens no painel Registos.

    Captura de ecrã do editor de funções do Azure, com os separadores Teste e Registos apresentados.

    A guia Saída mostra que um campo de status foi adicionado corretamente a cada uma das leituras.

  2. No menu Desenvolvedor à esquerda, selecione Monitor para ver se a solicitação foi registrada no Application Insights. O painel Monitor é exibido para sua função.

    A guia Invocações do painel exibe Rastreamentos de Invocação para cada uma das invocações de função. Selecione o valor Date(UTC) para uma das invocações e visualize os detalhes sobre a execução da sua função.