Connettere Funzioni di Azure ad Archiviazione di Azure con Visual Studio Code

La soluzione Funzioni di Azure consente di connettere i servizi di Azure e altre risorse alle funzioni senza la necessità di scrivere codice di integrazione personalizzato. Questi binding, che rappresentano sia input che output, vengono dichiarati all'interno della definizione di funzione. I dati dei binding vengono forniti alla funzione come parametri. Un trigger è un tipo speciale di binding di input. Anche se una funzione include un solo trigger, può avere più binding di input e output. Per altre informazioni, vedere Concetti su trigger e binding di Funzioni di Azure.

Questo articolo illustra come usare Visual Studio Code per connettersi Archiviazione di Azure alla funzione creata nell'articolo di avvio rapido precedente. Il binding di output che si aggiunge a questa funzione scrive i dati della richiesta HTTP in un messaggio della coda di Archiviazione code di Azure.

La maggior parte dei binding richiede una stringa di connessione archiviata che verrà usata da Funzioni per accedere al servizio associato. Per semplificare l'uso dell'account di archiviazione creato con l'app per le funzioni. La connessione a questo account è già archiviata in un'impostazione dell'app denominata AzureWebJobsStorage.

Nota

Questo articolo supporta attualmente solo Node.js v3 per Funzioni.

Configurare l'ambiente locale

Prima di iniziare, è necessario soddisfare i requisiti seguenti:

Questo articolo presuppone che sia già stato eseguito l'accesso alla sottoscrizione di Azure da Visual Studio Code. È possibile accedere eseguendo Azure: Sign In dal riquadro comandi.

Scaricare le impostazioni dell'app per le funzioni

Nell'articolo di avvio rapido precedente è stata creata un'app per le funzioni in Azure insieme all'account di archiviazione necessario. Il stringa di connessione per questo account viene archiviato in modo sicuro nelle impostazioni dell'app in Azure. In questo articolo verranno scritti messaggi in una coda di archiviazione dello stesso account. Per connettersi all'account di archiviazione quando si esegue la funzione in locale, è necessario scaricare le impostazioni dell'app nel file local.settings.json .

  1. Premere F1 per aprire il riquadro comandi, quindi cercare ed eseguire il comando Azure Functions: Download Remote Settings....

  2. Scegliere l'app per le funzioni creata nell'articolo precedente. Selezionare Sì per tutti per sovrascrivere le impostazioni locali esistenti.

    Importante

    Poiché il file local.settings.json contiene segreti, non viene mai pubblicato ed è escluso dal controllo del codice sorgente.

  3. Copiare il valore AzureWebJobsStorage, ovvero la chiave per l'account di archiviazione stringa di connessione valore. Usare questa connessione per verificare se il binding di output funziona come previsto.

Registrare le estensioni delle associazioni

Dato che si usa un binding di output di Archiviazione code, è necessario che l'estensione dei binding di archiviazione sia installata prima di eseguire il progetto.

Il progetto è stato configurato per l'uso di bundle di estensione, che installano automaticamente un set predefinito di pacchetti di estensione.

I bundle di estensione sono già abilitati nel file host.json alla radice del progetto, che dovrebbe essere simile all'esempio seguente:

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[3.*, 4.0.0)"
  }
}

Ora è possibile aggiungere il binding di output di archiviazione nel progetto.

Ad eccezione dei trigger HTTP e timer, i binding vengono implementati come pacchetti di estensione. Eseguire il comando dotnet add package seguente nella finestra del terminale per aggiungere il pacchetto di estensione di archiviazione nel progetto.

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues --prerelease

Ora è possibile aggiungere il binding di output di archiviazione nel progetto.

Aggiungere un binding di output

In Funzioni ogni tipo di associazione richiede un oggetto direction, typee univoco name. Il modo in cui si definiscono questi attributi dipende dal linguaggio dell'app per le funzioni.

Gli attributi di associazione vengono definiti nel file function.json per una determinata funzione. A seconda del tipo di binding, potrebbero essere necessarie altre proprietà. La tabella di configurazione dell'output della coda indica i campi necessari per un binding della coda di archiviazione di Azure. L'estensione semplifica l'aggiunta di associazioni al file function.json .

Per creare un'associazione, fare clic con il pulsante destro del mouse (CTRL+clic su macOS) sul function.json file nella cartella HttpTrigger e scegliere Aggiungi binding.... Seguire le istruzioni per definire le proprietà di associazione seguenti per la nuova associazione:

Richiesta Valore Descrizione
Selezionare la direzione di binding out Il binding è un binding di output.
Selezionare il binding con direzione Azure Queue Storage Il binding è un binding della coda di archiviazione di Azure.
Il nome usato per identificare questo binding nel codice msg Nome che identifica il parametro di binding a cui viene fatto riferimento nel codice.
La coda a cui verrà inviato il messaggio outqueue Il nome della coda in cui scrive il binding. Se queueName non esiste, il binding lo crea al primo utilizzo.
Selezionare l'impostazione da "local.setting.json" AzureWebJobsStorage Il nome dell'impostazione dell'applicazione che contiene la stringa di connessione per l'account di archiviazione. L'impostazione AzureWebJobsStorage contiene la stringa di connessione per l'account di archiviazione creato con l'app per le funzioni.

Un'associazione viene aggiunta alla bindings matrice nel function.json, che dovrebbe essere simile alla seguente:

{
  "type": "queue",
  "direction": "out",
  "name": "msg",
  "queueName": "outqueue",
  "connection": "AzureWebJobsStorage"
}

Gli attributi di associazione vengono definiti mediante la decorazione di codice di funzione specifico nel file function_app.py . Si usa l'elemento queue_output Decorator per aggiungere un'associazione di output dell'archiviazione code di Azure.

Usando l'elemento Decorator, la direzione dell'associazione queue_output è in modo implicito "out" e il tipo è Archiviazione di Azure Coda. Aggiungere l'elemento Decorator seguente al codice della funzione in HttpExample\function_app.py:

@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")

In questo codice, arg_name identifica il parametro di associazione a cui si fa riferimento nel codice, queue_name è il nome della coda in cui scrive l'associazione e connection è il nome di un'impostazione dell'applicazione che contiene il stringa di connessione per l'account Archiviazione. Negli argomenti di avvio rapido si usa lo stesso account di archiviazione dell'app per le funzioni, che si trova nell'impostazione AzureWebJobsStorage . Se queue_name non esiste, il binding lo crea al primo utilizzo.

In un progetto C# le associazioni vengono definite come attributi di associazione nel metodo della funzione. Definizioni specifiche dipendono dal fatto che l'app venga eseguita in-process (libreria di classi C#) o in un processo di lavoro isolato.

Aprire il file di progetto HttpExample.cs e aggiungere la classe seguente MultiResponse :

public class MultiResponse
{
    [QueueOutput("outqueue",Connection = "AzureWebJobsStorage")]
    public string[] Messages { get; set; }
    public HttpResponseData HttpResponse { get; set; }
}

La MultiResponse classe consente di scrivere in una coda di archiviazione denominata outqueue e in un messaggio HTTP riuscito. È possibile inviare più messaggi alla coda perché l'attributo QueueOutput viene applicato a una matrice di stringhe.

La Connection proprietà imposta il stringa di connessione per l'account di archiviazione. In questo caso, è possibile omettere Connection, perché si usa già l'account di archiviazione predefinito.

In un progetto Java i binding vengono definiti come annotazioni di binding nel metodo della funzione. Il file function.json viene quindi generato automaticamente in base a queste annotazioni.

Passare al percorso del codice della funzione, src/main/java, aprire il file di progetto Function.java e aggiungere il parametro seguente alla definizione del metodo run:

@QueueOutput(name = "msg", queueName = "outqueue", 
connection = "AzureWebJobsStorage") OutputBinding<String> msg,

Il parametro msg è un tipo OutputBinding<T>, che rappresenta una raccolta di stringhe scritte come messaggi in un binding di output al completamento della funzione. In questo caso, l'output è una coda di archiviazione denominata outqueue. La stringa di connessione per l'account di archiviazione è impostata dal metodo connection. Invece della stringa di connessione stessa, passare l'impostazione applicazione che contiene la stringa di connessione dell'account di archiviazione.

La definizione del metodo run dovrà ora essere come indicato nell'esempio seguente:

@FunctionName("HttpExample")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) 
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", 
        connection = "AzureWebJobsStorage") OutputBinding<String> msg, 
        final ExecutionContext context) {

Aggiungere il codice che usa l'associazione di output

Una volta definito il binding, è possibile usare il relativo valore name per accedervi come attributo nella firma della funzione. Usando un binding di output, non è necessario usare il codice di Azure Storage SDK per l'autenticazione, per recuperare un riferimento alla coda o per scrivere dati. Queste attività vengono eseguite automaticamente dal runtime di Funzioni e dal binding di output.

Aggiungere il codice che usa l'oggetto msg del binding di output in context.bindings per creare un messaggio della coda. Aggiungere questo codice prima dell'istruzione context.res.

// Add a message to the Storage queue,
// which is the name passed to the function.
context.bindings.msg = (req.query.name || req.body.name);

A questo punto, la funzione potrebbe essere simile alla seguente:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (req.query.name || (req.body && req.body.name)) {
        // Add a message to the Storage queue,
        // which is the name passed to the function.
        context.bindings.msg = (req.query.name || req.body.name);
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

Aggiungere il codice che usa l'oggetto msg del binding di output in context.bindings per creare un messaggio della coda. Aggiungere questo codice prima dell'istruzione context.res.

context.bindings.msg = name;

A questo punto, la funzione deve essere simile alla seguente:

import { AzureFunction, Context, HttpRequest } from "@azure/functions"

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    context.log('HTTP trigger function processed a request.');
    const name = (req.query.name || (req.body && req.body.name));

    if (name) {
        // Add a message to the storage queue, 
        // which is the name passed to the function.
        context.bindings.msg = name; 
        // Send a "hello" response.
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

export default httpTrigger;

Aggiungere il codice che usa il cmdlet Push-OutputBinding per scrivere un testo nella coda usando il binding di output msg. Aggiungere questo codice prima di impostare lo stato OK nell'istruzione if.

$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg

A questo punto, la funzione deve essere simile alla seguente:

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
}

if ($name) {
    # Write the $name value to the queue, 
    # which is the name passed to the function.
    $outputMsg = $name
    Push-OutputBinding -name msg -Value $outputMsg

    $status = [HttpStatusCode]::OK
    $body = "Hello $name"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

Aggiornare HttpExample\function_app.py in modo che corrisponda al codice seguente, aggiungere il msg parametro alla definizione della funzione e msg.set(name) sotto l'istruzione if name: :

import azure.functions as func
import logging

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

@app.route(route="HttpExample")
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
def HttpExample(req: func.HttpRequest, msg: func.Out [func.QueueMessage]) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        msg.set(name)
        return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
    else:
        return func.HttpResponse(
             "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

Il parametro msg è un'istanza della azure.functions.Out class. Il set metodo scrive un messaggio stringa nella coda. In questo caso, viene name passato alla funzione nella stringa di query URL.

Sostituire la classe esistente HttpExample con il codice seguente:

    [Function("HttpExample")]
    public static MultiResponse Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
        FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger("HttpExample");
        logger.LogInformation("C# HTTP trigger function processed a request.");

        var message = "Welcome to Azure Functions!";

        var response = req.CreateResponse(HttpStatusCode.OK);
        response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
        response.WriteString(message);

        // Return a response to both HTTP trigger and storage output binding.
        return new MultiResponse()
        {
            // Write a single message.
            Messages = new string[] { message },
            HttpResponse = response
        };
    }
}

Ora è possibile usare il nuovo parametro msg per scrivere nel binding di output dal codice della funzione. Aggiungere la riga di codice seguente prima della risposta di operazione riuscita per aggiungere il valore di name al binding di output msg.

msg.setValue(name);

Quando si usa un binding di output, non è necessario usare il codice di Azure Storage SDK per l'autenticazione, per recuperare un riferimento alla coda o per scrivere dati. Queste attività vengono eseguite automaticamente dal runtime di Funzioni e dal binding di output.

Il metodo run dovrà ora essere come indicato nell'esempio seguente:

@FunctionName("HttpExample")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) 
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", 
        connection = "AzureWebJobsStorage") OutputBinding<String> msg, 
        final ExecutionContext context) {
    context.getLogger().info("Java HTTP trigger processed a request.");

    // Parse query parameter
    String query = request.getQueryParameters().get("name");
    String name = request.getBody().orElse(query);

    if (name == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
        .body("Please pass a name on the query string or in the request body").build();
    } else {
        // Write the name to the message queue. 
        msg.setValue(name);

        return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
    }
}

Aggiornare i test

Poiché l'archetipo crea anche un set di test, è necessario aggiornare questi test per gestire il nuovo parametro msg nella firma del metodo run.

Passare al percorso del codice di test, src/test/java, aprire il file di progetto Function.java e sostituire la riga di codice sotto //Invoke con il codice seguente.

@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);

Eseguire la funzione in locale

Visual Studio Code si integra con Azure Functions Core Tools per consentire l'esecuzione di questo progetto nel computer di sviluppo locale prima della pubblicazione in Azure. Se Core Tools non è già installato in locale, viene richiesto di installarlo la prima volta che si esegue il progetto.

  1. Per chiamare la funzione, premere F5 per avviare il progetto di app per le funzioni. Il pannello Terminale visualizza l'output di Core Tools. L'app viene avviata nel pannello Terminale. È possibile visualizzare l'endpoint dell'URL della funzione attivata da HTTP eseguita in locale.

    Screenshot dell'output di Visual Studio Code per la funzione locale.

    Se Core Tools non è già installato, selezionare Installa per installare Core Tools quando richiesto.
    In caso di problemi con l'esecuzione in Windows, assicurarsi che il terminale predefinito per Visual Studio Code non sia impostato su WSL Bash.

  2. Con Gli strumenti di base in esecuzione passare all'area Azure: Funzioni . In Funzioni espandere Progetto locale>Funzioni. Fare clic con il pulsante destro del mouse (Windows) o CTRL - (macOS) sulla funzione HttpExample e scegliere Execute Function Now... (Esegui funzione adesso).

    Screenshot della funzione execute now da Visual Studio Code.

  3. Nel corpo della richiesta INVIO premere INVIO per inviare un messaggio di richiesta alla funzione.

  4. Quando la funzione viene eseguita in locale e restituisce una risposta, viene generata una notifica in Visual Studio Code. Le informazioni sull'esecuzione della funzione vengono visualizzate nel pannello Terminale .

  5. Premere CTRL+C per arrestare Core Tools e disconnettere il debugger.

Eseguire la funzione in locale

  1. Come nell'articolo precedente, premere F5 per avviare il progetto dell'app per le funzioni e Core Tools.

  2. Con Gli strumenti di base in esecuzione passare all'area Azure: Funzioni . In Funzioni espandere Progetto locale>Funzioni. Fare clic con il pulsante destro del mouse (ctrl+clic su Mac) sulla HttpExample funzione e selezionare Esegui funzione ora....

    Screenshot dell'esecuzione della funzione da Visual Studio Code.

  3. Nel corpo della richiesta Invio viene visualizzato il valore del corpo del messaggio di richiesta .{ "name": "Azure" } Premere INVIO per inviare il messaggio di richiesta alla funzione.

  4. Dopo la restituzione di una risposta, premere CTRL+C per arrestare Core Tools.

Poiché si usa il stringa di connessione di archiviazione, la funzione si connette all'account di archiviazione di Azure durante l'esecuzione in locale. Quando il binding di output viene usato per la prima volta, nell'account di archiviazione viene creata dal runtime di Funzioni una nuova coda denominata outqueue. Usare Storage Explorer per verificare che siano stati creati la coda e un nuovo messaggio.

Connettere Storage Explorer all'account

Ignorare questa sezione se è già stato installato Archiviazione di Azure Explorer e connesso all'account Azure.

  1. Eseguire lo strumento Azure Storage Explorer, selezionare l'icona della connessione a sinistra, quindi selezionare Aggiungi un account.

    Screenshot di come aggiungere un account Azure a Archiviazione di Microsoft Azure Explorer.

  2. Nella finestra di dialogo Connessione scegliere Aggiungi un account Azure, scegliere l'ambiente Azure e quindi selezionare Accedi....

    Screenshot della finestra di accesso all'account Azure.

Dopo aver eseguito l'accesso all'account, verranno visualizzate le sottoscrizioni di Azure associate. Scegliere la sottoscrizione e selezionare Apri Esplora risorse.

Esaminare la coda di output

  1. In Visual Studio Code premere F1 per aprire il riquadro comandi, quindi cercare ed eseguire il comando Azure Storage: Open in Storage Explorer e scegliere il nome dell'account di archiviazione. L'account di archiviazione viene aperto nel Archiviazione di Azure Explorer.

  2. Espandere il nodo Code e quindi selezionare la coda denominata outqueue.

    La coda contiene il messaggio creato dall'associazione di output della coda quando è stata eseguita la funzione attivata da HTTP. Se la funzione è stata richiamata con il valore predefinito di nameAzure, il messaggio della coda è Name passed to the function: Azure.

    Screenshot del messaggio della coda visualizzato in Archiviazione di Azure Explorer.

  3. Eseguire di nuovo la funzione, inviare un'altra richiesta e visualizzare un nuovo messaggio nella coda.

Ora è il momento di ripubblicare l'app per le funzioni aggiornata in Azure.

Ridistribuire e verificare l'app aggiornata

  1. In Visual Studio Code premere F1 per aprire il riquadro comandi. Nel riquadro comandi cercare e selezionare Azure Functions: Deploy to function app....

  2. Scegliere l'app per le funzioni creata nel primo articolo. Poiché il progetto viene ridistribuito nella stessa app, selezionare Distribuisci per ignorare l'avviso sulla sovrascrittura di file.

  3. Al termine della distribuzione, è possibile usare di nuovo la funzionalità Esegui funzione ora... per attivare la funzione in Azure.

  4. Visualizzare di nuovo il messaggio nella coda di archiviazione per verificare che l'associazione di output generi un nuovo messaggio nella coda.

Pulire le risorse

In Azure il termine risorse si riferisce ad app per le funzioni, funzioni, account di archiviazione e così via. Le risorse sono raggruppate in gruppi di risorse, ed è possibile eliminare tutti gli elementi in un gruppo eliminando il gruppo.

Sono state create risorse per completare queste guide introduttive. Per tali risorse potrebbero venire addebitati costi, a seconda dello stato dell'account e dei prezzi dei servizi. Se le risorse non sono più necessarie, ecco come eliminarle:

  1. In Visual Studio Code premere F1 per aprire il riquadro comandi. Nel riquadro comandi cercare e selezionare Azure: Open in portal.

  2. Scegliere l'app per le funzioni e premere INVIO. La pagina dell'app per le funzioni viene aperta nel portale di Azure.

  3. Nella scheda Panoramica selezionare il collegamento accanto a Gruppo di risorse.

    Screenshot della selezione del gruppo di risorse da eliminare dalla pagina dell'app per le funzioni.

  4. Nella pagina Gruppo di risorse esaminare l'elenco delle risorse incluse e verificare che siano quelle da eliminare.

  5. Selezionare Elimina gruppo di risorse e seguire le istruzioni.

    L'eliminazione potrebbe richiedere alcuni minuti. Al termine, viene visualizzata una notifica per pochi secondi. È anche possibile selezionare l'icona a forma di campana nella parte superiore della pagina per visualizzare la notifica.

Passaggi successivi

La funzione di trigger HTTP è stata aggiornata per scrivere dati in una coda di archiviazione. A questo punto, è possibile ottenere maggiori informazioni sullo sviluppo di funzioni con Visual Studio Code: