Připojení Azure Functions na Azure Storage pomocí nástrojů příkazového řádku

v tomto článku integrujete frontu Azure Storage pomocí funkce a účtu úložiště, který jste vytvořili v předchozím článku rychlý start. Tuto integraci dosáhnete pomocí výstupní vazby , která zapisuje data z požadavku HTTP do zprávy ve frontě. Po dokončení tohoto článku se neúčtují žádné další náklady nad několik centů za USD předchozího rychlého startu. Další informace o vazbách naleznete v tématu Azure Functions triggery a koncepty vazeb.

Konfigurace místního prostředí

Než začnete, musíte dokončit článek, rychlý Start: vytvoření Azure Functions projektu z příkazového řádku. Pokud jste již vyčistili prostředky na konci tohoto článku, Projděte kroky znovu a znovu vytvořte aplikaci funkcí a související prostředky v Azure.

Než začnete, musíte dokončit článek, rychlý Start: vytvoření Azure Functions projektu z příkazového řádku. Pokud jste již vyčistili prostředky na konci tohoto článku, Projděte kroky znovu a znovu vytvořte aplikaci funkcí a související prostředky v Azure.

Než začnete, musíte dokončit článek, rychlý Start: vytvoření Azure Functions projektu z příkazového řádku. Pokud jste již vyčistili prostředky na konci tohoto článku, Projděte kroky znovu a znovu vytvořte aplikaci funkcí a související prostředky v Azure.

Než začnete, musíte dokončit článek, rychlý Start: vytvoření Azure Functions projektu z příkazového řádku. Pokud jste již vyčistili prostředky na konci tohoto článku, Projděte kroky znovu a znovu vytvořte aplikaci funkcí a související prostředky v Azure.

Než začnete, musíte dokončit článek, rychlý Start: vytvoření Azure Functions projektu z příkazového řádku. Pokud jste již vyčistili prostředky na konci tohoto článku, Projděte kroky znovu a znovu vytvořte aplikaci funkcí a související prostředky v Azure.

Než začnete, musíte dokončit článek, rychlý Start: vytvoření Azure Functions projektu z příkazového řádku. Pokud jste již vyčistili prostředky na konci tohoto článku, Projděte kroky znovu a znovu vytvořte aplikaci funkcí a související prostředky v Azure.

načtení připojovacího řetězce Azure Storage

dříve jste vytvořili účet Azure Storage, který bude používat aplikace function app. Připojovací řetězec pro tento účet je bezpečně uložený v nastavení aplikace v Azure. stažením nastavení do local.settings.jsv souboru můžete toto připojení použít do fronty Storage ve stejném účtu při místní funkci.

  1. Z kořenového adresáře projektu spusťte následující příkaz a nahraďte <APP_NAME> názvem vaší aplikace Function za předchozím rychlým startem. Tento příkaz přepíše všechny existující hodnoty v souboru.

    func azure functionapp fetch-app-settings <APP_NAME>
    
  2. otevřete local.settings.js a vyhledejte hodnotu s názvem AzureWebJobsStorage , což je připojovací řetězec účtu Storage. Název AzureWebJobsStorage a připojovací řetězec použijete v dalších částech tohoto článku.

Důležité

Vzhledem k tomu, že local.settings.jsna obsahuje tajné kódy stažené z Azure, tento soubor vždycky vylučte ze správy zdrojového kódu. Soubor . gitignore vytvořený pomocí projektu místní funkce vyloučí soubor ve výchozím nastavení.

Registrace rozšíření vazeb

S výjimkou triggerů HTTP a časovače jsou vazby implementované jako balíčky rozšíření. Spuštěním následujícího příkazu dotnet add package v okně Terminálu přidejte do Storage balíček rozšíření.

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

Teď můžete do projektu přidat výstupní vazbu úložiště.

Přidání definice výstupní vazby do funkce

I když funkce může mít jenom jednu Trigger, může mít víc vstupních a výstupních vazeb, které vám umožní připojit se k dalším službám a prostředkům Azure bez nutnosti psát vlastní kód pro integraci.

Tyto vazby deklarujete v function.js souboru ve složce Functions. Z předchozího rychlého startu vaše function.js v souboru ve složce HttpExample obsahují dvě vazby v bindings kolekci:

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

Každá vazba má alespoň typ, směr a název. V předchozím příkladu je první vazba typu httpTrigger s směrem in . Pro in směr name Určuje název vstupního parametru, který je odeslán funkci při vyvolání triggerem.

Druhá vazba v kolekci je pojmenována res . Tato http vazba je výstupní vazba ( out ), která se používá k zápisu odpovědi HTTP.

Chcete-li z této funkce zapisovat do fronty Azure Storage, přidejte out vazbu typu queue s názvem msg , jak je znázorněno v následujícím kódu:

    {
      "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"
    }
  ]
}

Druhá vazba v kolekci je typu http s směrem out . v takovém případě name $return to znamená, že tato vazba používá návratovou hodnotu funkce namísto zadání vstupního parametru.

Chcete-li z této funkce zapisovat do fronty Azure Storage, přidejte out vazbu typu queue s názvem msg , jak je znázorněno v následujícím kódu:

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

Druhá vazba v kolekci je pojmenována res . Tato http vazba je výstupní vazba ( out ), která se používá k zápisu odpovědi HTTP.

Chcete-li z této funkce zapisovat do fronty Azure Storage, přidejte out vazbu typu queue s názvem msg , jak je znázorněno v následujícím kódu:

    {
      "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"
    }
  ]
}

V tomto případě msg je funkce předána funkci jako výstupní argument. Pro queue typ musíte zadat také název fronty v queueName a zadat název Azure Storageho připojení (od local.settings.jszapnuto) v connection .

V projektu jazyka C# jsou vazby definovány jako atributy vazby v metodě funkce. Konkrétní definice závisí na tom, jestli vaše aplikace běží v procesu (knihovna tříd C#), nebo v izolovaném procesu.

Otevřete soubor projektu HttpExample.cs a do definice metody přidejte Run následující parametr:

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

Parametr msg je typ, který představuje kolekci zpráv, které jsou zapsány do výstupní vazby po ICollector<T> dokončení funkce. V tomto případě je výstupem fronta úložiště s názvem outqueue . Připojovací řetězec pro účet Storage se nastavuje pomocí StorageAccountAttribute . Tento atribut označuje nastavení, které obsahuje Storage připojovací řetězec účtu a lze ho použít na úrovni třídy, metody nebo parametru. V takovém případě můžete vynechat , StorageAccountAttribute protože už používáte výchozí účet úložiště.

Definice metody Run by teď měla vypadat takto:

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

V projektu Java jsou vazby definovány jako anotace vazby v metodě Function. function.jsv souboru se pak automaticky generuje na základě těchto poznámek.

Přejděte do umístění kódu funkce v části Src/Main/Java, otevřete soubor projektu Function. Java a do definice metody přidejte následující parametr run :

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

msgParametr je OutputBinding<T> typ, který představuje kolekci řetězců, které jsou zapsány jako zprávy do výstupní vazby po dokončení funkce. V tomto případě je výstupem fronta úložiště s názvem outqueue . Připojovací řetězec pro účet úložiště je nastaven connection metodou. Místo samotného připojovacího řetězce předáte nastavení aplikace, které obsahuje připojovací řetězec účtu úložiště.

runDefinice metody by teď měla vypadat jako v následujícím příkladu:

@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) {
    ...
}

Další informace o podrobnostech vazeb najdete v tématu Azure Functions triggery a koncepty vazeb a Konfigurace výstupu fronty.

Přidat kód pro použití výstupní vazby

Je-li definována vazba fronty, můžete nyní aktualizovat funkci tak, aby přijímala msg výstupní parametr, a zapisovat zprávy do fronty.

Aktualizujte soubor HttpExample \ _ _ init _ _ .py tak, aby odpovídal následujícímu kódu, a přidejte parametr do definice funkce a msg pod příkaz msg.set(name) 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
        )

Parametr msg je instance azure.functions.Out class . Jeho metoda zapíše do fronty řetězcovou zprávu, v tomto případě název předaný funkci set v řetězci dotazu adresy URL.

Přidejte kód, který používá msg výstupní vazbu objektu pro context.bindings k vytvoření zprávy fronty. Přidejte tento kód před context.res příkaz.

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

V tomto okamžiku by měla funkce vypadat takto:

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

Přidejte kód, který používá msg výstupní vazbu objektu pro context.bindings k vytvoření zprávy fronty. Přidejte tento kód před context.res příkaz.

context.bindings.msg = name;

V tomto okamžiku by měla funkce vypadat takto:

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;

Přidejte kód, který používá Push-OutputBinding rutinu k zápisu textu do fronty pomocí msg výstupní vazby. Před nastavením stavu OK v příkazu přidejte tento kód if .

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

V tomto okamžiku by měla funkce vypadat takto:

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

Přidejte kód, který používá msg výstupní objekt vazby k vytvoření zprávy fronty. Před vrácením metody přidejte tento kód.

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

V tomto okamžiku by měla funkce vypadat takto:

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

Nyní můžete použít nový msg parametr pro zápis do výstupní vazby z kódu funkce. Přidejte následující řádek kódu před reakci na úspěch pro přidání hodnoty name do msg výstupní vazby.

msg.setValue(name);

Když použijete výstupní vazbu, nemusíte používat Azure Storage kód SDK pro ověřování, získání odkazu na frontu nebo zápis dat. Úlohy za běhu functions a Queue výstupní vazby jsou za vás.

Vaše run Metoda by teď měla vypadat jako v následujícím příkladu:

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

Aktualizace testů

Vzhledem k tomu, že Archetype také vytvoří sadu testů, je nutné aktualizovat tyto testy pro zpracování nového msg parametru v run signatuře metody.

Přejděte do umístění testovacího kódu v části Src/test/Java, otevřete soubor projektu Function. Java a nahraďte řádek kódu //Invoke následujícím kódem.

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

Pozor , abyste nemuseli psát žádný kód pro ověřování, získání odkazu na frontu nebo zápis dat. Všechny tyto úkoly integrace jsou pohodlně zpracovávány v Azure Functions modul runtime a výstupní vazba fronty.

Místní spuštění funkce

  1. Spusťte funkci spuštěním místního hostitele modulu runtime Azure Functions ze složky LocalFunctionProj :

    func start
    

    Ke konci výstupu by se měly zobrazit následující řádky:

     ...
    
     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
     ...
    
     

    Poznámka

    Pokud se HttpExample nezobrazí, jak je uvedeno výše, pravděpodobně jste spustili hostitele mimo kořenovou složku projektu. V takovém případě pomocí kombinace kláves CTRL + + C zastavte hostitele, přejděte do kořenové složky projektu a spusťte předchozí příkaz znovu.

  2. Zkopírujte adresu URL vaší HttpExample funkce z tohoto výstupu do prohlížeče a přidejte řetězec dotazu ?name=<YOUR_NAME> , jako je třeba celá adresa URL http://localhost:7071/api/HttpExample?name=Functions . V prohlížeči by se měla zobrazit zpráva odpovědi, která vrací zpět hodnotu řetězce dotazu. Terminál, ve kterém jste spustili projekt, také zobrazuje výstup protokolu při provádění požadavků.

  3. Až budete hotovi, použijte CTRL + C a vyberte možnost y zastavit hostitele funkcí.

Tip

Během spouštění hostitel stáhne a nainstaluje rozšíření vazby úložiště a další rozšíření Microsoft Binding Extensions. K této instalaci dochází, protože rozšíření vazby jsou ve výchozím nastavení povolena v host.jsv souboru s následujícími vlastnostmi:

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

Pokud narazíte na chyby související s rozšířeními vazby, ověřte, že jsou v host.jsk dispozici výše uvedené vlastnosti.

zobrazení zprávy ve frontě Azure Storage

Tuto frontu můžete zobrazit v Azure Portal nebo v Průzkumník služby Microsoft Azure Storage. Tuto frontu můžete také zobrazit v rozhraní příkazového řádku Azure CLI, jak je popsáno v následujících krocích:

  1. Otevřetelocal.setting.jsprojektu funkce na soubor a zkopírujte hodnotu připojovacího řetězce. V terminálu nebo okně příkazového řádku spusťte následující příkaz, který vytvoří proměnnou prostředí s názvem AZURE_STORAGE_CONNECTION_STRING a místo ní bude vkládat konkrétní připojovací řetězec <MY_CONNECTION_STRING> . (Tato proměnná prostředí znamená, že nemusíte zadávat připojovací řetězec ke každému následujícímu příkazu pomocí --connection-string argumentu.)

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. Volitelné Pomocí az storage queue list příkazu Zobrazte ve svém účtu fronty úložiště. Výstup z tohoto příkazu by měl zahrnovat frontu s názvem outqueue , která byla vytvořena při zapsání první zprávy do této fronty.

    az storage queue list --output tsv
    
  3. Pomocí az storage message get příkazu si přečtěte zprávu z této fronty, která by měla být křestní jméno, které jste použili při předchozím testování funkce. Příkaz přečte a Odebere první zprávu z fronty.

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

    Vzhledem k tomu, že tělo zprávy je uložené v kódování Base64, je nutné zprávu dekódovat předtím, než se zobrazí. Po spuštění bude az storage message get zpráva odebrána z fronty. Pokud v nástroji existovala jenom jedna zpráva outqueue , při spuštění tohoto příkazu se nezobrazí zpráva a místo toho se zobrazí chyba.

Opětovné nasazení projektu do Azure

teď, když jste místně ověřili, že funkce zapsala zprávu do fronty Azure Storage, můžete projekt znovu nasadit, aby se aktualizoval koncový bod běžící v Azure.

Ve složce LocalFunctionsProj použijte func azure functionapp publish příkaz pro opětovné nasazení projektu a nahraďte <APP_NAME> názvem vaší aplikace.

func azure functionapp publish <APP_NAME>

V místní složce projektu použijte následující příkaz Maven pro opětovné publikování projektu:

mvn azure-functions:deploy

Ověření v Azure

  1. Stejně jako v předchozím rychlém startu použijte k otestování znovu nasazené funkce prohlížeč nebo KUDRLINKOU.

    Zkopírujte úplnou adresu URL pro vyvolání zobrazenou ve výstupu příkazu publikovat do adresního řádku prohlížeče a přidejte parametr dotazu &name=Functions . V prohlížeči by se měl zobrazit podobný výstup jako při spuštění funkce místně.

    Výstup funkce se spouští v Azure v prohlížeči.

  2. znovu zkontrolujte frontu Storage, jak je popsáno v předchozí části, a ověřte tak, že obsahuje novou zprávu zapsanou do fronty.

Vyčištění prostředků

Po dokončení použijte následující příkaz k odstranění skupiny prostředků a všech jejích obsažených prostředků, abyste se vyhnuli vzniku dalších nákladů.

az group delete --name AzureFunctionsQuickstart-rg

Další kroky

aktualizovali jste funkci aktivovanou protokolem HTTP, která zapisuje data do fronty Storage. Nyní se můžete dozvědět víc o vývoji funkcí z příkazového řádku pomocí základních nástrojů a Azure CLI: