Поделиться через


Подключение Azure Functions к Azure Storage с помощью кода Visual Studio

Azure Functions позволяет подключать Azure службы и другие ресурсы к функциям без написания собственного кода интеграции. Эти привязки, которые представляют как входные, так и выходные данные, объявляются в определении функции. Данные привязок предоставляются функции в качестве параметров. Триггер является специальным типом входных привязок. Хотя функция обладает только одним триггером, она может состоять из нескольких входных и выходных привязок. Дополнительные сведения см. тут: Концепции триггеров и привязок Azure Functions.

В этой статье вы узнаете, как использовать код Visual Studio для подключения Azure Storage к функции, созданной в предыдущей краткой статье. Выходная привязка, добавляемая в эту функцию, записывает данные из HTTP-запроса в сообщение в очереди Azure Queue storage.

Для большинства привязок требуется сохраненная строка подключения, которую функции используют для доступа к связанной службе. Чтобы упростить работу, используйте учетную запись хранения, которую вы создали с приложением Function. Подключение к этой учетной записи уже хранится в параметрах приложения под названием AzureWebJobsStorage.

Примечание.

В настоящее время эта статья поддерживает Node.js версии 4 для функций.

Настройка локальной среды

Перед началом необходимо выполнить следующие требования:

  • Установите расширение Azure Storage для Visual Studio Code.

  • Установите Azure Storage Explorer. Storage Explorer — это средство, которое будет использоваться для проверки сообщений очереди, созданных выходной привязкой. Storage Explorer поддерживается в операционных системах под управлением MacOS, Windows и Linux.

В этой статье предполагается, что вы уже вошли в подписку Azure из кода Visual Studio. Вы можете войти в систему, запустив Azure: Sign In из палитры команд.

Загрузка параметров приложения-функции

В предыдущем быстром старте вы создали приложение-функцию в Azure вместе с необходимой учетной записью хранения. Строка подключения для этой учетной записи безопасно хранится в настройках приложения в Azure. В этой статье вы записываете сообщения в очередь Storage в той же учетной записи. Чтобы подключиться к учетной записи хранилища при локальном запуске функции, необходимо скачать параметры приложения в файл local.settings.json.

  1. Нажмите клавишу F1, чтобы открыть палитру команд, а затем выполните поиск команды Azure Functions: Download Remote Settings....

  2. Выберите созданное в рамках предыдущей статьи приложение-функцию. Выберите Да, для всех, чтобы перезаписать имеющиеся локальные параметры.

    Внимание

    Из-за того, что файла local.settings.json содержит секреты, этот файл никогда не будет опубликован — он будет исключен из системы управления версиями.

  3. Скопируйте значение AzureWebJobsStorage, которое является ключом для строки подключения учетной записи. Это подключение используется для проверки работы выходной привязки.

Регистрация расширений привязки

Так как вы используете выходную привязку очереди storage, перед запуском project необходимо установить расширение Storage привязок.

Ваша проект настроен на использование пакетов расширений, которые автоматически устанавливают предопределенный набор пакетов расширений.

Пакеты расширений уже включены в файле host.json в корне project, который должен выглядеть следующим образом:

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

Теперь вы можете добавить выходную привязку хранилища в ваш проект.

Ваш проект настроен на использование наборов расширений , которые автоматически устанавливают предопределенный набор пакетов расширений.

Пакеты расширений уже включены в файле host.json в корне project, который должен выглядеть следующим образом:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

Теперь вы можете добавить внешнюю привязку хранилища в проект.

За исключением триггеров HTTP и таймера, привязки реализованы в виде пакетов расширений. Выполните следующую команду dotnet add package в окне терминала, чтобы добавить пакет расширения Storage в project.

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

Теперь вы можете добавить в ваш проект привязку к хранилищу.

Добавление выходной привязки

Чтобы записать в очередь Azure Storage:

  • Добавьте свойство extraOutputs в конфигурацию привязки

    {
        methods: ['GET', 'POST'],
        extraOutputs: [sendToQueue], // add output binding to HTTP trigger
        authLevel: 'function',
        handler: () => {}
    }
    
  • Добавьте функцию output.storageQueue перед вызовом app.http.

    const sendToQueue = output.storageQueue({
      queueName: 'outqueue',
      connection: 'AzureWebJobsStorage',
    });
    

Как записать в очередь Azure Storage:

  • Добавьте свойство extraOutputs в конфигурацию привязки

    {
        methods: ['GET', 'POST'],
        extraOutputs: [sendToQueue], // add output binding to HTTP trigger
        authLevel: 'function',
        handler: () => {}
    }
    
  • Добавьте функцию output.storageQueue перед вызовом app.http.

    const sendToQueue: StorageQueueOutput = output.storageQueue({
      queueName: 'outqueue',
      connection: 'AzureWebJobsStorage',
    });
    

В Функциях для каждого типа привязки требуется direction, type и уникальный name. Способ определения этих атрибутов зависит от языка приложения-функции.

Атрибуты привязки определяются в файле function.json для данной функции. В зависимости от типа привязки могут потребоваться дополнительные свойства. Конфигурация вывода queue описывает поля, необходимые для привязки очереди Azure Storage. Расширение упрощает добавление привязок в файл function.json .

Чтобы создать привязку, щелкните правой кнопкой мыши (CTRL+щелкните macOS) function.json файл в папке HttpTrigger и нажмите кнопку "Добавить привязку...". Следуйте инструкциям, чтобы определить следующие свойства привязки для новой привязки:

Подсказка значение Описание
Select binding direction (Выберите направление привязки) out Привязка является выходной привязкой.
Select binding with direction... (Выберите привязку с направлением...) Azure Queue Storage Привязка является привязкой к очереди в системе Azure Storage.
The name used to identify this binding in your code (Имя, используемое для идентификации этой привязки в коде) msg Имя, которое используется для идентификации параметров привязки, указанных в коде.
The queue to which the message will be sent (Очередь, в которую будет отправляться сообщение) outqueue Имя очереди, в которую записывается привязка. Если queueName не существует, то при первом использовании этот параметр будет создан привязкой.
Select setting from "local.setting.json" (Выберите параметр из файла local.setting.json) AzureWebJobsStorage Имя параметра приложения, содержащего connection string для учетной записи Storage. Параметр AzureWebJobsStorage содержит строку подключения для учетной записи хранилища, созданной с помощью функционального приложения.

Привязка добавляется к массиву bindings в function.json, который должен выглядеть следующим образом:

      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Атрибуты привязки определяются путем декорирования определенного кода функции в файле function_app.py . Вы используете декоратор , чтобы добавить выходную привязку хранения Azure Queue .

При использовании декоратора queue_output направление привязки неявно устанавливается как "out", а тип - очередь Azure Storage. Добавьте следующий декоратор в код функции в function_app.py:

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

В этом коде arg_name определяет параметр привязки, на который ссылается код, queue_name — имя очереди, в которую записывается привязка, и connection — это имя параметра приложения, содержащего connection string для учетной записи Storage. В кратких руководствах используется та же учетная запись хранилища, что и у приложения функции, которое также находится в параметре AzureWebJobsStorage. Если queue_name не существует, то при первом использовании привязка создаст этот параметр.

В project C# привязки определяются как атрибуты привязки в методе функции. Конкретные определения зависят от того, выполняется ли приложение в процессе (библиотека классов C#) или в изолированном рабочем процессе.

Откройте файл HttpExample.cs project и добавьте следующий класс MultiResponse:

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

Класс MultiResponse позволяет записывать в очередь хранения с именем outqueue и отправлять сообщение об успешном выполнении HTTP. Так как атрибут QueueOutput применяется к массиву строк, в очередь можно отправить несколько сообщений.

Свойство Connection задает строку подключения для учетной записи хранилища. В этом случае можно опустить Connection, так как вы уже используете учетную запись storage по умолчанию.

В проекте Java привязки определяются как аннотации привязки на методе функции. Затем на основе этих заметок автоматически создается файл function.json.

Перейдите к расположению кода функции в разделе src/main/java откройте файл Function.java project и добавьте следующий параметр в определение метода run:

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

Параметр msg — это тип OutputBinding<T>, представляющий коллекцию строк, записанных в виде сообщений в выходную привязку после завершения функции. В этом случае результат — это очередь хранения с именем outqueue. Строка подключения для учетной записи хранилища устанавливается методом connection. Вместо самой строки подключения передайте параметр приложения, содержащий строку подключения к учетной записи Storage.

Определение метода run теперь должно выглядеть следующим образом:

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

Добавление кода, который использует выходную привязку

После определения привязки можно использовать name привязки, чтобы получать доступ к ней в качестве атрибута в сигнатуре функции. Используя выходную привязку, вам не нужно использовать код пакета SDK Azure Storage для проверки подлинности, получения ссылки на очередь или записи данных. Среда выполнения Azure Functions и привязка выходной очереди выполняют эти задачи за вас.

Добавьте код, использующий объект выходной привязки context.extraOutputs для создания сообщения в очереди. Добавьте этот код перед оператором return.

context.extraOutputs.set(sendToQueue, [msg]);

На этом этапе функция может выглядеть следующим образом:

const { app, output } = require('@azure/functions');

const sendToQueue = output.storageQueue({
  queueName: 'outqueue',
  connection: 'AzureWebJobsStorage',
});

app.http('HttpExample', {
  methods: ['GET', 'POST'],
  authLevel: 'anonymous',
  extraOutputs: [sendToQueue],
  handler: async (request, context) => {
    try {
      context.log(`Http function processed request for url "${request.url}"`);

      const name = request.query.get('name') || (await request.text());
      context.log(`Name: ${name}`);

      if (name) {
        const msg = `Name passed to the function ${name}`;
        context.extraOutputs.set(sendToQueue, [msg]);
        return { body: msg };
      } else {
        context.log('Missing required data');
        return { status: 404, body: 'Missing required data' };
      }
    } catch (error) {
      context.log(`Error: ${error}`);
      return { status: 500, body: 'Internal Server Error' };
    }
  },
});

Добавьте код, использующий объект выходной привязки context.extraOutputs для создания сообщения в очереди. Добавьте этот код перед оператором return.

context.extraOutputs.set(sendToQueue, [msg]);

На этом этапе функция может выглядеть следующим образом:

import {
  app,
  output,
  HttpRequest,
  HttpResponseInit,
  InvocationContext,
  StorageQueueOutput,
} from '@azure/functions';

const sendToQueue: StorageQueueOutput = output.storageQueue({
  queueName: 'outqueue',
  connection: 'AzureWebJobsStorage',
});

export async function HttpExample(
  request: HttpRequest,
  context: InvocationContext,
): Promise<HttpResponseInit> {
  try {
    context.log(`Http function processed request for url "${request.url}"`);

    const name = request.query.get('name') || (await request.text());
    context.log(`Name: ${name}`);

    if (name) {
      const msg = `Name passed to the function ${name}`;
      context.extraOutputs.set(sendToQueue, [msg]);
      return { body: msg };
    } else {
      context.log('Missing required data');
      return { status: 404, body: 'Missing required data' };
    }
  } catch (error) {
    context.log(`Error: ${error}`);
    return { status: 500, body: 'Internal Server Error' };
  }
}

app.http('HttpExample', {
  methods: ['GET', 'POST'],
  authLevel: 'anonymous',
  handler: HttpExample,
});

Добавьте код, использующий командлет Push-OutputBinding для записи текста в очередь с помощью привязки выходных данных msg. Добавьте этот код перед установкой состояния "ОК" в выражении if.

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

На этом этапе ваша функция должна выглядеть так:

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

Обновите HttpExample\function_app.py, чтобы он соответствовал следующему коду, добавив параметр msg в определение функции и msg.set(name) в выражении 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
        )

Параметр msg является экземпляром azure.functions.Out class. Метод set записывает строковое сообщение в очередь. В этом случае name передается в функцию в строке запроса URL-адреса.

Замените существующий Run метод следующим кодом:

[Function("HttpExample")]
public MultiResponse Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
{
    _logger.LogInformation("C# HTTP trigger function processed a request.");

    var message = "Welcome to Azure Functions!";

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

Теперь для записи в выходную привязку из кода функции вы можете использовать новый параметр msg. Добавьте следующую строку кода перед успешным ответом, чтобы добавить значение name к выходной привязке msg.

msg.setValue(name);

При использовании выходной привязки вам не нужно использовать код пакета SDK Azure Storage для проверки подлинности, получения ссылки на очередь или записи данных. Среда выполнения Azure Functions и привязка выходной очереди выполняют эти задачи за вас.

Теперь метод run должен выглядеть следующим образом:

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

Обновление тестов

Поскольку архетип также создает набор тестов, необходимо обновить эти тесты для обработки нового параметра msg в сигнатуре метода run.

Перейдите к расположению тестового кода в разделе src/test/java откройте файл Function.java project и замените строку кода в //Invoke следующим кодом.

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

Локальное выполнение функции

Visual Studio Code интегрируется с Azure Functions Core Tools, чтобы иметь возможность запускать этот проект на вашем локальном компьютере для разработки, прежде чем опубликовать в Azure. Если у вас еще не установлены Core Tools, вам будет предложено установить их при первом запуске вашего проекта.

  1. Чтобы вызвать функцию, нажмите клавишу F5, чтобы запустить проект приложения-функции. На панели Терминал отобразятся выходные данные из Core Tools. Ваше приложение запускается в панели Терминал. Отобразится URL-адрес конечной точки активируемой HTTP-запросом функции, которая выполняется локально.

    Скриншот вывода функции Local в Visual Studio Code.

    Если у вас еще не установлены Core Tools, выберите Install, чтобы установить Core Tools, когда будет предложено.
    Если у вас проблемы с запуском Windows, убедитесь, что терминал по умолчанию для Visual Studio Code не установлен на WSL Bash.

  2. При запущенных Core Tools перейдите в раздел Azure: Функции. В разделе Functions разверните Local Project>Functions. Щелкните правой кнопкой мыши (в Windows) или используйте Ctrl-щелчок (в macOS) на функции HttpExample и выберите Выполнить функцию....

    Скриншот функции выполнения кода в среде Visual Studio Code.

  3. В поле Введите текст запроса нажмите клавишу ВВОД, чтобы отправить запрос в функцию.

  4. Когда функция выполняется локально и возвращает ответ, уведомление создается в Visual Studio Code. Сведения о выполнении функции отображаются на панели Терминал.

  5. Нажмите клавиши CTRL+C, чтобы остановить Core Tools и отключить отладчик.

Локальное выполнение функции

  1. Как и в предыдущей статье, нажмите F5, чтобы запустить проект приложения-функции и Core Tools.

  2. Когда инструменты Core запущены, перейдите в раздел Azure: Функции. В разделе Functions разверните Local Project>Functions. Щелкните правой кнопкой мыши (Ctrl-щелчок на компьютерах Mac) функцию HttpExample и выберите Выполнить функцию....

    Снимок экрана выполнения функции из Visual Studio Code.

  3. В тексте запроса Enter отображается значение текста сообщения запроса { "name": "Azure" }. Нажмите клавишу ВВОД, чтобы отправить это сообщение запроса в вашу функцию.

  4. После возврата ответа нажмите клавиши CTRL+C, чтобы остановить работу Core Tools.

Так как вы используете storage connection string, функция подключается к учетной записи Azure storage при локальном запуске. Новая очередь с именем outqueue создается в учетной записи хранения в среде выполнения Functions при первом использовании выходной привязки. Вы будете использовать Storage Explorer, чтобы убедиться, что очередь была создана вместе с новым сообщением.

Подключение Storage Explorer к учетной записи

Пропустите этот раздел, если вы уже установили Azure Storage Explorer и подключили его к учетной записи Azure.

  1. Запустите средство Azure Storage Explorer, щелкните значок подключения слева и выберите Добавить учетную запись.

    Скриншот, демонстрирующий добавление учетной записи Azure в Microsoft Azure Storage Explorer.

  2. В диалоговом окне Connect выберите Add an Azure account, выберите среду Azure/c2>< и выберите Sign in... .

    Скриншот окна входа в учетную запись Azure.

После успешного входа в учетную запись вы увидите все Azure подписки, связанные с вашей учетной записью. Выберите подписку и выберите "Открыть обозреватель".

Проверьте выходную очередь

  1. В коде Visual Studio нажмите клавишу F1, чтобы открыть палитру команд, а затем выполните поиск и выполните команду Azure Storage: Open in Storage Explorer и выберите имя учетной записи storage. Ваша учетная запись хранилища откроется в Azure Storage Explorer.

  2. Разверните узел Очереди, а затем выберите очередь с именем outqueue.

    В ней содержится сообщение о том, что выходная привязка очереди создана при запуске функции, активируемой HTTP. Если вы вызвали функцию со значением по умолчанию Azure, сообщение в очереди: Имя, переданное функции: Azure.

    Скриншот сообщения из очереди, показанного в Azure Storage Explorer.

  3. Запустите функцию еще раз, отправьте другой запрос, и в очереди появится новое сообщение.

Теперь пришло время повторно опубликовать обновленное приложение-функцию для Azure.

Повторное развертывание и проверка обновленного приложения

  1. В коде Visual Studio нажмите клавишу F1, чтобы открыть палитру команд. В палитре команд найдите и выберите Azure Functions: Deploy to function app....

  2. Выберите созданное в рамках первой статьи приложение-функцию. Поскольку вы повторно развертываете проект в том же приложении, выберите Развернуть, чтобы закрыть предупреждение о перезаписи файлов.

  3. После завершения развертывания можно снова использовать функцию Execute Now... функция для активации функции в Azure. Эта команда автоматически извлекает ключ доступа функции и использует его при вызове конечной точки триггера HTTP.

  4. Снова просмотрите сообщение в очереди хранилища, чтобы убедиться, что выходная привязка создает новое сообщение в очереди.

Очистка ресурсов

В Azure ресурсы относятся к функциональным приложениям, функциям, учетным записям хранилища и т. д. Они объединяются в группы ресурсов, и вы можете удалить всё в группе, удалив группу.

Вы создали ресурсы для завершения этих кратких руководств. Вас могут выставить счет за эти ресурсы в зависимости от статуса аккаунта и тарифов на услуги. Если вам больше не нужны ресурсы, их можно удалить следующим образом:

  1. В коде Visual Studio нажмите клавишу F1, чтобы открыть палитру команд. В палитре команд найдите и выберите Azure: Open in portal.

  2. Выберите приложение-функцию и нажмите клавишу ВВОД. Откроется страница приложения-функции в Azure portal.

  3. На вкладке Обзор выберите именованную ссылку рядом с полем Группа ресурсов.

    Снимок экрана: выбор группы ресурсов, которую требуется удалить со страницы приложения-функции.

  4. На странице Группа ресурсов просмотрите список включенных ресурсов и убедитесь, что именно их нужно удалить.

  5. Выберите Удалить группу ресурсов и следуйте инструкциям.

    Удаление может занять несколько минут. После этого на несколько секунд появится уведомление. Кроме того, можно выбрать значок колокольчика в верхней части страницы, чтобы просмотреть уведомление.

Следующие шаги

Вы обновили функцию, активированную HTTP, чтобы записывать данные в очередь хранилища. Теперь вы можете узнать больше о разработке функций с помощью кода Visual Studio: