Esercizio - Aggiungi la logica all'applicazione di 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.

Aggiungi una funzione alla tua 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 Funzione App, sotto la scheda Funzioni e Crea nel portale di Azure, selezionare Crea funzione. Viene visualizzato il riquadro Crea funzione.

  3. In Seleziona un modello selezionare Trigger HTTP e Avanti.

  1. Lasciare Nome funzione come HttpTrigger1 e livello di autorizzazione come Funzione, e selezionare Crea. La funzione HttpTrigger1 viene creata e visualizzata nel riquadro Funzione HttpTrigger1.

  2. Selezionare la scheda 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 Nome funzione. Lasciare Livello di autorizzazione impostato su Funzione e quindi selezionare Crea per creare la funzione. Viene visualizzato il riquadro Panoramica per la funzione 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 logframe dovrebbe iniziare ad acquisire 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 il collegamento _master (chiave host) 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 del portale di Azure che visualizza l'editor delle funzioni con il pulsante Recupera URL della funzione evidenziato.

  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.

    La risposta dovrebbe essere simile al seguente.

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

    Ora passa il 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"
    

    La risposta dovrebbe essere simile al seguente.

    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, il livello è impostato 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 i tasti di funzione, aprire il menu Codice e test selezionando il nome della funzione (ad esempio, HttpTriger1) nella scheda Funzioni del menu Panoramica. Selezionare quindi la scheda Chiavi 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 che mostra il riquadro Chiavi di funzione con il tasto funzione evidenziato.

  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.
    • È stata utilizzata una richiesta POST.
    • È stata passata la funzione di Azure con l'URL per la funzione.
  5. Controlla i registri.

    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 viene inviata alla funzione. Il nome della matrice potrebbe essere leggermente diverso per JavaScript o PowerShell, ma ogni voce della matrice ha 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
        }
    ]
}

Sostituire il codice predefinito nella funzione con il codice seguente che implementa 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.

Testare la logica aziendale

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

  1. Nella scheda Codice e test selezionare Test/Esegui. 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
            }
        ]
    }
    

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.

Prendi nota delle chiamate al cmdlet Write-Host. Quando la funzione viene eseguita, queste istruzioni aggiungono messaggi nella finestra Log.

Testare la logica aziendale

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

  1. Nella scheda Codice e test selezionare Test/Esegui. 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
            }
        ]
    }
    
  1. 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 del riquadro (se non è già aperta). L'immagine seguente illustra un esempio di risposta nel riquadro di output e i messaggi nel riquadro Log.

    Screenshot dell'editor delle funzioni di Azure, con le schede Test e Log visualizzate.

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