Azure Functions verbinden met Azure Storage met behulp van opdrachtregelhulpprogramma's

In dit artikel integreert u een Azure Storage-wachtrij met de functie die en het opslagaccount dat u in het vorige quickstart-artikel hebt gemaakt. De integratie wordt mogelijk gemaakt door uitvoerbinding die gegevens schrijft van een HTTP-aanvraag naar een bericht in de wachtrij. Het voltooien van dit artikel brengt geen extra kosten met zich mee, behalve de paar dollarcent die tijdens de vorige quickstart zijn uitgegeven. Zie Concepten van Azure Functions-triggers en -bindingen voor meer informatie over bindingen.

Uw lokale omgeving configureren

Voordat u begint, moet u het volgende artikel voltooien: Quickstart: een Azure Functions-project maken via de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het volgende artikel voltooien: Quickstart: een Azure Functions-project maken via de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het volgende artikel voltooien: Quickstart: een Azure Functions-project maken via de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het volgende artikel voltooien: Quickstart: een Azure Functions-project maken via de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het volgende artikel voltooien: Quickstart: een Azure Functions-project maken via de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het volgende artikel voltooien: Quickstart: een Azure Functions-project maken via de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Azure Storage-verbindingsreeks ophalen

U hebt eerder een Azure Storage-account gemaakt dat door de functie-app moet worden gebruikt. De verbindingsreeks voor dit account wordt veilig opgeslagen in de app-instellingen in Azure. Door de instelling in het bestand local.settings.json te downloaden, kunt u deze verbinding gebruiken om naar een Storage-wachtrij in hetzelfde account te schrijven wanneer u de functie lokaal uitvoert.

  1. Voer in de hoofdmap van het project de volgende opdracht uit en vervang <APP_NAME> door de naam van uw functie-app uit de vorige quickstart. Met deze opdracht worden alle bestaande waarden in het bestand overschreven.

    func azure functionapp fetch-app-settings <APP_NAME>
    
  2. Open het bestand local.settings.json en zoek waarde AzureWebJobsStorage. Dit is de verbindingsreeks voor het Storage-account. U gebruikt de naam AzureWebJobsStorage en de verbindingsreeks in andere secties van dit artikel.

Belangrijk

Omdat local.settings.json geheimen bevat die zijn gedownload van Azure, moet u dit bestand altijd uitsluiten van broncodebeheer. Met het bestand .gitignore, dat met een lokaal Functions-project is gemaakt, wordt het bestand standaard uitgesloten.

Binding-extensies registreren

Met uitzondering van HTTP- en timertriggers worden bindingen geïmplementeerd als uitbreidingspakketten. Voer de volgende dotnet add package-opdracht in het terminalvenster uit om het Storage-extensiepakket toe te voegen aan uw project.

dotnet add package Microsoft.Azure.WebJobs.Extensions.Storage 

Nu kunt u de Storage-uitvoerbinding toevoegen aan uw project.

Een definitie van een uitvoerbinding toevoegen aan de functie

Hoewel een functie slechts één trigger kan hebben, kan deze meerdere in- en uitvoerbindingen hebben, zodat u verbinding kunt maken met andere Azure-services en -resources zonder dat u aangepaste integratiecode hoeft te schrijven.

U declareert deze bindingen in het bestand function.json in de map function. Door de vorige quickstart bevat uw bestand function.json in de map HttpExample twee bindingen in de verzameling bindings:

"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "res"
    }
]
"scriptFile": "__init__.py",
"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "$return"
    }
"bindings": [
  {
    "authLevel": "function",
    "type": "httpTrigger",
    "direction": "in",
    "name": "Request",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "Response"
  }
]

Elke binding heeft ten minste een type, een richting en een naam. In het bovenstaande voorbeeld heeft de eerste binding het type httpTrigger en de richting in. Voor de richting in is name de naam van een invoerparameter die naar de functie wordt verzonden wanneer deze wordt aangeroepen door de trigger.

De tweede binding in de verzameling heeft de naam res. Deze http-binding is een uitvoerbinding (out) die wordt gebruikt voor het schrijven van het HTTP-antwoord.

Als u vanuit deze functie naar een Azure Storage-wachtrij wilt schrijven, voegt u een out-binding van het type queue met de naam msg toe, zoals wordt weergegeven in de onderstaande code:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

De tweede binding in de verzameling heeft het type http en de richting out, in welk geval de speciale name van $return aangeeft dat deze binding de retourwaarde van de functie gebruikt in plaats van een invoerparameter aan te leveren.

Als u vanuit deze functie naar een Azure Storage-wachtrij wilt schrijven, voegt u een out-binding van het type queue met de naam msg toe, zoals wordt weergegeven in de onderstaande code:

"bindings": [
  {
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "$return"
  },
  {
    "type": "queue",
    "direction": "out",
    "name": "msg",
    "queueName": "outqueue",
    "connection": "AzureWebJobsStorage"
  }
]

De tweede binding in de verzameling heeft de naam res. Deze http-binding is een uitvoerbinding (out) die wordt gebruikt voor het schrijven van het HTTP-antwoord.

Als u vanuit deze functie naar een Azure Storage-wachtrij wilt schrijven, voegt u een out-binding van het type queue met de naam msg toe, zoals wordt weergegeven in de onderstaande code:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

In dit geval wordt msg als uitvoerargument aan de functie doorgegeven. Voor een binding van het type queue moet u ook de naam van de wachtrij opgeven in queueName en de naam van de Azure Storage-verbinding (uit local.settings.json) in connection opgeven.

In een C#-project worden de bindingen gedefinieerd als bindingskenmerken in de functiemethode. Specifieke definities zijn afhankelijk van of uw app wordt uitgevoerd in-process (C#-klassebibliotheek) of in een geïsoleerd proces.

Open het projectbestand HttpExample.cs en voeg de volgende parameter toe aan de methodedefinitie Run:

[Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg,

De parameter msg is een type ICollector<T> die een verzameling berichten vertegenwoordigt die worden geschreven naar een uitvoerbinding wanneer de functie is voltooid. In dit geval is de uitvoer een opslagwachtrij met de naam outqueue. De verbindingsreeks voor het Storage-account wordt ingesteld door de StorageAccountAttribute. Dit kenmerk geeft de instelling aan die de verbindingsreeks van het Storage-account bevat en kan worden toegepast op het niveau van de klasse, methode of parameter. In dit geval kunt u StorageAccountAttribute weglaten, omdat u dit al gebruikt in het standaardopslagaccount.

De uitvoermethodedefinitie moet er nu als volgt uitzien:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)

In een Java-project worden de bindingen gedefinieerd als bindingsaantekeningen in de functiemethode. Het bestand function.json wordt vervolgens automatisch gegenereerd op basis van deze aantekeningen.

Blader naar de locatie van de functiecode onder src/main/java, open het projectbestand Function.java en voeg de volgende parameter aan de methodedefinitie run toe:

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

Parameter msg is van het type OutputBinding<T>, dat een verzameling berichten voorstelt die naar een uitvoerbinding wordt geschreven wanneer de functie is voltooid. In dit geval is de uitvoer een opslagwachtrij met de naam outqueue. De verbindingsreeks voor het Storage-account wordt ingesteld door de methode connection. In plaats van de verbindingsreeks zelf, geeft u de toepassingsinstelling door die de verbindingsreeks voor het Storage-account bevat.

De methodedefinitie run moet er nu uitzien als in het volgende voorbeeld:

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

Zie Concepten van Azure Functions-triggers en -bindingen en Configuratie van de wachtrijuitvoer voor meer informatie over bindingen.

Code toevoegen die gebruikmaakt van de uitvoerbinding

Als de wachtrijbinding is gedefinieerd, kunt u de functie bijwerken om de uitvoerparameter msg te ontvangen en berichten te schrijven naar de wachtrij.

Werkt HttpExample\__init__.py bij om overeen te komen met de volgende code en voeg de parameter msg toe aan de functiedefinitie en msg.set(name) onder de instructie if name:.

import logging

import azure.functions as func


def main(req: func.HttpRequest, msg: func.Out[func.QueueMessage]) -> str:

    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}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )

De parameter msg is een instantie van de azure.functions.Out class. De methode set schrijft een tekenreeksbericht naar de wachtrij, in dit geval de naam die aan de functie is doorgegeven in de URL-querytekenreeks.

Voeg code toe die het bindingsobject van de uitvoer msg in context.bindings gebruikt om een wachtrijbericht te maken. Voeg deze code toe vóór de instructie 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);

Op dit moment moet uw functie er als volgt uit zien:

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

Voeg code toe die het bindingsobject van de uitvoer msg in context.bindings gebruikt om een wachtrijbericht te maken. Voeg deze code toe vóór de instructie context.res.

context.bindings.msg = name;

Op dit moment moet uw functie er als volgt uit zien:

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;

Voeg code toe die gebruikmaakt van de cmdlet Push-OutputBinding om tekst te schrijven naar de wachtrij met de uitvoerbinding msg. Voeg deze code toe voordat u de status Ok in de instructie if instelt.

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

Op dit moment moet uw functie er als volgt uit zien:

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

Voeg code toe die het bindingsobject van de uitvoer msg gebruikt om een wachtrijbericht te maken. Voeg deze code toe voordat de methode wordt geretourneerd.

if (!string.IsNullOrEmpty(name))
{
    // Add a message to the output collection.
    msg.Add(string.Format("Name passed to the function: {0}", name));
}

Op dit moment moet uw functie er als volgt uit zien:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    if (!string.IsNullOrEmpty(name))
    {
        // Add a message to the output collection.
        msg.Add(string.Format("Name passed to the function: {0}", name));
    }
    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

U kunt nu de nieuwe parameter, msg, gebruiken om naar de uitvoerbinding van uw functiecode te schrijven. Voordat u het antwoord krijgt dat de bewerking is geslaagd, voegt u de volgende regel code toe om de waarde van name aan de msg-uitvoerbinding toe te voegen.

msg.setValue(name);

Als u een uitvoerbinding gebruikt, hoeft u niet de Azure Storage SDK-code voor verificatie te gebruiken, een wachtrijverwijzing op te halen of gegevens te schrijven. Deze taken worden voor u verwerkt via Functions-runtime en Queue Storage-uitvoerbinding.

De methode run moet er nu uitzien als in het volgende voorbeeld:

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

De tests bijwerken

Omdat het archetype ook een reeks tests maakt, moet u deze tests bijwerken om de nieuwe parameter msg in de handtekening van methode run te verwerken.

Blader naar de locatie van de testcode onder src/test/java, open projectbestand Function.java en vervang de regel met code onder //Invoke door de volgende code.

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

Houd er rekening mee dat u geen code hoeft te schrijven voor verificatie, het ophalen van een wachtrijverwijzing of het schrijven van gegevens. Al deze integratietaken kunnen worden verwerkt in de Azure Functions-runtime en in de wachtrijuitvoerbinding.

De functie lokaal uitvoeren

  1. Voer uw functie uit door de lokale Azure Functions runtime host te starten vanuit de map LocalFunctionProj:

    func start
    

    Naar het einde van de uitvoer moeten de volgende regels worden weergegeven:

     ...
    
     Now listening on: http://0.0.0.0:7071
     Application started. Press Ctrl+C to shut down.
    
     Http Functions:
    
             HttpExample: [GET,POST] http://localhost:7071/api/HttpExample
     ...
    
     

    Notitie

    Als HttpExample niet verschijnt zoals hierboven weergegeven, hebt u waarschijnlijk de host gestart van buiten de hoofdmap van het project. In dat geval gebruikt u Ctrl+C om de host te stoppen, gaat u naar de hoofdmap van het project en voert u de vorige opdracht opnieuw uit.

  2. Kopieer de URL van uw HttpExample-functie van deze uitvoer naar een browser en voeg de query tekenreeks toe ?name=<YOUR_NAME>, waardoor de volledige URL verschijnt, zoals http://localhost:7071/api/HttpExample?name=Functions. In de browser wordt een antwoord bericht weer gegeven waarin de waarde van de query reeks wordt geretourneerd. De terminal waarin u uw project hebt gestart, toont ook de logboek uitvoer wanneer u aanvragen doet.

  3. Wanneer u klaar bent, gebruikt u Ctrl+C en kiest u y om de functiehost te stoppen.

Tip

Tijdens het opstarten downloadt en installeert de host de Storage-bindingsextensie en andere Microsoft-bindingsextensies. Deze installatie vindt plaats omdat bindingsextensies standaard zijn ingeschakeld in het host. json-bestand met de volgende eigenschappen:

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

Als u fouten ondervindt met bindingsextensies, controleert u of host. json de bovenstaande eigenschappen bevat.

Het bericht weergeven in de wachtrij van Azure Storage

U kunt de wachtrij bekijken in de Azure Portal of in de Microsoft Azure Storage Explorer. U kunt de wachtrij ook bekijken in de Azure CLI, zoals wordt beschreven in de volgende stappen:

  1. Open het bestand local.setting.json van het functieproject en kopieer de verbindingsreekswaarde. Voer in een terminal- of opdrachtvenster de volgende opdracht uit om een omgevingsvariabele met de naam AZURE_STORAGE_CONNECTION_STRING te maken en uw specifieke verbindingsreeks in plaats van <MY_CONNECTION_STRING> te plakken. (Deze omgevingsvariabele zorgt ervoor dat u de verbindingsreeks niet hoeft op te geven bij elke volgende opdracht met het argument --connection-string.)

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. (Optioneel) Gebruik de opdracht az storage queue list om de opslagwachtrijen in uw account te bekijken. De uitvoer van deze opdracht moet een wachtrij bevatten met de naam outqueue, die is gemaakt toen de functie het eerste bericht naar die wachtrij heeft geschreven.

    az storage queue list --output tsv
    
  3. Gebruik de opdracht az storage message get om het bericht uit deze wachtrij te lezen. Dit moet de voornaam zijn die u eerder hebt gebruikt bij het testen van de functie. Met deze opdracht leest en verwijdert u het eerste bericht in de wachtrij.

    echo `echo $(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`
    

    Omdat de berichttekst base64-gecodeerd is opgeslagen, moet het bericht worden gedecodeerd voordat het kan worden weergegeven. Nadat u az storage message get hebt uitgevoerd, wordt het bericht uit de wachtrij verwijderd. Als er slechts één bericht in outqueue was, wordt er geen bericht weergegeven wanneer u deze opdracht een tweede keer uitvoert en wordt in plaats daarvan een foutmelding weergegeven.

Het project opnieuw implementeren in Azure

Nu u lokaal hebt gecontroleerd of de functie een bericht naar de Azure Storage-wachtrij heeft geschreven, kunt u uw project opnieuw implementeren om het eindpunt in Azure bij te werken.

Gebruik in de map LocalFunctionsProj de opdracht func azure functionapp publish om het project opnieuw te implementeren, waarbij u <APP_NAME> vervangt door de naam van uw app.

func azure functionapp publish <APP_NAME>

Gebruik in de lokale projectmap de volgende Maven-opdracht om het project opnieuw te publiceren:

mvn azure-functions:deploy

Verifiëren in Azure

  1. Net als in de vorige quickstart gebruikt u een browser of CURL om de opnieuw geïmplementeerde functie te testen.

    Kopieer de volledige Aanroep-URL die wordt weergegeven in de uitvoer van de publicatieopdracht naar de adresbalk van een browser en voeg de queryparameter &name=Functions toe. De browser moet vergelijkbare uitvoer weergeven als u de functie lokaal hebt uitgevoerd.

    De uitvoer van de functie die wordt uitgevoerd in Azure, in een browser

  2. Controleer de opslagwachtrij opnieuw, zoals beschreven in de vorige sectie, om te controleren of deze het nieuwe bericht bevat dat naar de wachtrij is geschreven.

Resources opschonen

Wanneer u klaar bent, gebruikt u de volgende opdracht om de resourcegroep en alle bijbehorende resources te verwijderen om te voorkomen dat er verdere kosten in rekening worden gebracht.

az group delete --name AzureFunctionsQuickstart-rg

Volgende stappen

U hebt uw HTTP-geactiveerde functie bijgewerkt om gegevens naar een opslagwachtrij te schrijven. U kunt nu meer te weten komen over het ontwikkelen van functies via de opdrachtregel door gebruik te maken van Core Tools en de Azure CLI: