Esercizio - Aggiungere la logica all'app per le funzioni

Completato

Di seguito si proseguirà con l'esempio della trasmissione a ingranaggi aggiungendo la logica per il servizio relativo alla temperatura. In particolare, si riceveranno dati da una richiesta HTTP.

Requisiti della funzione

Innanzitutto, definire i requisiti per la logica:

  • Le temperature tra 0 e 25 gradi dovranno essere contrassegnate come OK.
  • Le temperature da 25 a 50 gradi dovranno essere contrassegnate come CAUTION.
  • Le temperature oltre i 50 gradi dovranno essere contrassegnate come DANGER.

Aggiungere una funzione all'app per le funzioni

Come descritto nell'unità precedente, Azure offre modelli che consentono di creare funzioni. In questa unità viene usato il modello HttpTrigger per implementare il servizio relativo alla temperatura.

  1. Nell'esercizio precedente l'app per le funzioni è stata distribuita e aperta. Se non è già aperta, è possibile farlo dalla home page selezionando Tutte le risorse e quindi selezionando l'app per le funzioni denominata in modo simile a escalation-functions-xxx.

  2. Nella schermata App per le funzioni nella scheda Funzioni selezionare Crea nel portale di Azure. Viene visualizzato il riquadro Crea funzione.

  3. In Seleziona un modello selezionare Trigger HTTP.

  1. Seleziona Crea. HttpTrigger1 viene creato e visualizzato nel riquadro Funzione HttpTrigger1.

  2. Nel menu Sviluppatore a sinistra selezionare Codice e test. Viene aperto l'editor di codice, che mostra il contenuto del file di codice index.js per la funzione. Nel frammento di codice seguente è riportato il codice predefinito che il modello HTTP ha generato automaticamente.

    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
        };
    }
    

    La funzione prevede il passaggio di un nome tramite la stringa della query di richiesta HTTP o come parte del corpo della richiesta. La funzione risponde restituendo il messaggio Hello, <nome>. Questa funzione di trigger HTTP è stata eseguita correttamente, ripetendo il nome che è stato inviato nella richiesta.

    Dall'elenco a discesa dei file di origine selezionare function.json per visualizzare la configurazione della funzione, che dovrebbe essere simile alla seguente.

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

    Con questa configurazione si dichiara che la funzione viene eseguita quando riceve una richiesta HTTP. L'associazione di output dichiara che la risposta è inviata come risposta HTTP.

  1. Nella sezione Dettagli modello, immettere DriveGearTemperatureService nel campo Nuova funzione. Lasciare Livello di autorizzazione impostato su Funzione e quindi selezionare Crea per creare la funzione. Viene visualizzato il riquadro Panoramica dell'app per le funzioni DriveGearTemperatureService.

  2. Nel menu Funzione selezionare Codice + Test. Si apre l'editor di codice con il contenuto del file di codice run.ps1. Nel frammento di codice seguente viene elencato il codice predefinito che il modello ha generato automaticamente.

    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
    })
    

    La funzione prevede il passaggio di un nome tramite la stringa della query di richiesta HTTP o come parte del corpo della richiesta. Le funzioni HTTP devono generare una risposta scrivendo nell'associazione di output. A tale scopo, nelle funzioni di PowerShell viene usato il cmdlet Push-OutputBinding. La funzione restituisce il messaggio Hello, $name, ripetendo il nome che è stato inviato nella richiesta.

  3. Dall'elenco a discesa del codice sorgente selezionare function.json per visualizzare la configurazione della funzione, che dovrebbe essere simile alla seguente.

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

    Con questa configurazione si dichiara che la funzione viene eseguita quando riceve una richiesta HTTP. L'associazione di output dichiara che la risposta è inviata come risposta HTTP.

Testare la funzione

Suggerimento

cURL è uno strumento da riga di comando che può essere usato per inviare o ricevere file. È incluso in Linux, macOS e Windows 10 e può essere scaricato per la maggior parte degli altri sistemi operativi. cURL supporta vari protocolli come HTTP, HTTPS, FTP, FTPS, SFTP, LDAP, TELNET, SMTP, POP3 e così via. Per altre informazioni, vedi i collegamenti seguenti:

Per testare la funzione, è possibile inviare una richiesta HTTP all'URL della funzione usando cURL dalla riga di comando.

  1. Espandere il frame Log nella parte inferiore del riquadro della funzione di trigger. Selezionare Log del file system nell'elenco a discesa nella parte superiore del frame Log. Il frame del log inizierà ad accumulare notifiche di traccia ogni minuto.

  2. Per trovare l'URL dell'endpoint della funzione, dalla barra dei comandi selezionare Recupera URL della funzione, come illustrato nell'immagine seguente. Salvare questo collegamento selezionando l'icona Copia negli Appunti alla fine dell'URL. Memorizzare questo collegamento nel Blocco note o in un'app simile per usarlo in seguito.

    Screenshot of the Azure portal showing the function editor, with the Get function URL button highlighted.

  3. Aprire un prompt dei comandi ed eseguire cURL per inviare una richiesta HTTP all'URL della funzione. Ricordare di utilizzare l'URL copiato nel passaggio precedente.

    curl "<your-https-url>"
    

    Suggerimento

    Potrebbe essere necessario eseguire il wrapping dell'URL tra virgolette per evitare problemi con caratteri speciali nell'URL.
    Se si usa Windows, eseguire il comando cURL dal prompt dei comandi. In PowerShell è presente un comando curl, ma è in realtà un alias di Invoke-WebRequest che non è identico a cURL.

    Le risposte saranno simili ai seguenti.

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

    Ora, passare un nome nella richiesta. A tale scopo, è necessario aggiungere un parametro della stringa query denominato name all'URL. Nell'esempio seguente viene aggiunto il parametro name=Azuredella stringa query.

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

    Le risposte saranno simili ai seguenti.

    Hello, Azure. This HTTP triggered function executed successfully.
    

    La funzione è stata eseguita correttamente e ha restituito il nome passato nella richiesta.

Proteggere i trigger HTTP

I trigger HTTP consentono di usare le chiavi API per bloccare i chiamanti sconosciuti, richiedendo che la chiave sia presente in ogni richiesta. Quando si crea una funzione si seleziona il livello di autorizzazione. Per impostazione predefinita, è impostata su Funzione, che richiede una chiave API specifica della funzione. Può anche essere impostato su amministratore per usare una chiave master globale oppure anonimo per indicare che non è necessaria alcuna chiave. Il livello di autorizzazione può essere modificato anche tramite le proprietà di funzione dopo la creazione.

Poiché è stato specificato Funzione durante la creazione di questa funzione, è necessario specificare la chiave quando si invia la richiesta HTTP. È possibile inviarlo come parametro della stringa di query denominato code. In alternativa, usare il metodo preferito e passarlo come intestazione HTTP denominata x-functions-key.

  1. Per trovare la funzione e le chiavi master, nel menu App per le funzioni, in Sviluppatore selezionare Chiavi di funzione. Si apre il riquadro Chiavi di funzione per la funzione.

  2. Per impostazione predefinita, il valore della chiave della funzione è nascosto. Visualizzare il valore predefinito della chiave della funzione selezionando Mostra valore. Copiare il contenuto del campo Valore negli Appunti e quindi archiviare il tasto nel Blocco note o in un'app simile per usarlo in un secondo momento.

    Screenshot showing the Function Keys pane with the revealed function key highlighted.

  3. Per testare la funzione con il tasto funzione, aprire un prompt dei comandi ed eseguire cURL per inviare una richiesta HTTP all'URL della funzione. Sostituire <your-function-key> con il valore della chiave di funzione salvato e sostituire <your-https-url> con l'URL della funzione.

    curl --header "Content-Type: application/json" --header "x-functions-key: <your-function-key>" --request POST --data "{\"name\": \"Azure Function\"}" <your-https-url>
    
  4. Esaminare il comando cURL e verificare che abbia i valori seguenti:

    • Aggiunto un valore dell'intestazione Content-Type di tipo application/json.
    • Passata la chiave di funzione come valore dell'intestazione x-functions-key.
    • Usata una richiesta POST.
    • È stata passata la funzione di Azure con l'URL per la funzione.
  5. Controllare i log.

    Il riquadro Codice e test aprirà una sessione che visualizza l'output del file di log. Assicurarsi che Log del file system sia selezionato nell'elenco a discesa nella parte superiore del riquadro Log. Il file di log viene aggiornato con lo stato della richiesta, che dovrebbe avere un aspetto simile al seguente:

```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)
```

Aggiungere la logica di business alla funzione

Ora aggiungiamo alla funzione la logica che controlla le letture delle temperature ricevute e imposta uno stato per ogni singola lettura.

La funzione prevede una matrice di letture della temperatura. Il frammento JSON seguente costituisce un esempio di corpo della richiesta che sarà inviata alla funzione. Ogni elemento reading possiede un ID, un timestamp e una temperatura.

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

Sostituiamo ora il codice predefinito della funzione con il codice seguente per implementare la logica di business.

Nel riquadro della funzione HttpTrigger1 aprire il file index.js e sostituirlo con il codice seguente. Dopo aver apportato questa modifica, nella barra dei comandi selezionare Salva per salvare gli aggiornamenti nel file.

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();
};

La logica che è stata aggiunta è semplice. È possibile eseguire l'iterazione tramite la matrice e impostare lo stato come OK, CAUTION o DANGER in base al valore del campo temperatura. La matrice delle letture viene quindi restituita dopo aver aggiunto il campo dello stato per ogni voce.

Prestare attenzione alle istruzioni Log quando si espande Log nella parte inferiore del riquadro. Quando la funzione viene eseguita, queste istruzioni aggiungono messaggi nella finestra Log.

Aprire il file run.ps1 e sostituirne il contenuto con il codice seguente. Dopo aver apportato questa modifica, nella barra dei comandi selezionare Salva per salvare gli aggiornamenti nel file.

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
})

La logica che è stata aggiunta è semplice. È possibile eseguire l'iterazione tramite la matrice e impostare lo stato come OK, CAUTION o DANGER in base al valore del campo temperatura. La matrice delle letture viene quindi restituita dopo aver aggiunto il campo dello stato per ogni voce.

Si notino le chiamate al cmdlet Write-Host. Quando la funzione viene eseguita, queste istruzioni aggiungono messaggi nella finestra Log.

Testare la logica di business

Verrà usata la funzionalità Test/Esegui in Sviluppatore>Codice + Test per testare la funzione.

  1. Nella scheda Input sostituire il contenuto della casella di testo Corpo con il codice seguente per creare la richiesta di esempio.

    {
        "readings": [
            {
                "driveGearId": 1,
                "timestamp": 1534263995,
                "temperature": 23
            },
            {
                "driveGearId": 3,
                "timestamp": 1534264048,
                "temperature": 45
            },
            {
                "driveGearId": 18,
                "timestamp": 1534264050,
                "temperature": 55
            }
        ]
    }
    
  2. Selezionare Esegui. La scheda Output mostra il codice e il contenuto della risposta HTTP. Per visualizzare i messaggi di log, aprire la scheda Log nel riquadro a comparsa nella parte inferiore del pannello, se non è già aperta. L'immagine seguente illustra un esempio di risposta nel riquadro di output e i messaggi nel riquadro Log.

    Screenshot of the Azure function editor, with the Test and Logs tabs showing.

    Nella scheda Output viene mostrato che il campo relativo allo stato è stato aggiunto correttamente per ogni lettura.

  3. Per verificare che la richiesta sia stata registrata in Application Insights, nel menu Sviluppatore a sinistra selezionare Monitoraggio. Viene visualizzato il riquadro Monitoraggio per la funzione.

    Nella scheda Chiamate del riquadro vengono visualizzate tracce di chiamata per ognuna delle chiamate di funzione. Selezionare il valore Date(UTC) per una delle chiamate e visualizzare i dettagli sull'esecuzione della funzione.