Упражнение. Добавление логики в приложение-функцию
Здесь мы продолжим работу с примером привода, добавив логику для службы контроля температуры. В частности, мы настроим получение данных через HTTP-запрос.
Требования к функции
Прежде всего давайте определим некоторые требования для нашей логики:
- температура от 0 до 25 градусов получает флаг ОК;
- температура от 25 до 50 градусов получает флаг ОСТОРОЖНО;
- температура выше 50 градусов получает флаг DANGER.
Добавление функции в приложение-функцию
Как уже говорилось на предыдущем уроке, предоставляемые Azure шаблоны помогут вам быстро к создавать функции. В этом уроке HttpTrigger
шаблон используется для реализации службы температуры.
В предыдущем упражнении вы развернули приложение-функцию и открыли ее. Если она еще не открыта, ее можно открыть на главной странице, выбрав Все ресурсы, а затем выбрав приложение-функцию с именем вида escalator-functions-xxx.
На экране приложения-функции на вкладке "Функции" выберите "Создать" в портал Azure. Откроется панель Создание функции.
В разделе "Выбор шаблона" выберите триггер HTTP и нажмите кнопку "Далее".
Оставьте имя функции как HttpTrigger1 и уровень авторизации как функция и нажмите кнопку "Создать". Функция HttpTrigger1 создается и отображается в области функций HttpTrigger1.
Перейдите на вкладку "Код и тест ". Откроется редактор кода, отображающий содержимое файла кода index.js для функции. Следующий фрагмент содержит код по умолчанию, который автоматически создается шаблоном HTTP.
module.exports = async function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); const name = (req.query.name || (req.body && req.body.name)); const responseMessage = name ? "Hello, " + name + ". This HTTP triggered function executed successfully." : "This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response."; context.res = { // status: 200, /* Defaults to 200 */ body: responseMessage }; }
Эта функция ожидает передачи имени или через строку HTTP-запроса, или в самом тексте запроса. В ответ функция возвращает сообщение Привет, <имя>. Функция, активируемая по HTTP, успешно выполнена., возвращая имя, отправленное в запросе.
В раскрывающемся списке исходного файла выберите файл function.json, содержимое которого выглядит так, как в коде ниже.
{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "direction": "in", "name": "req", "methods": [ "get", "post" ] }, { "type": "http", "direction": "out", "name": "res" } ] }
Этот файл конфигурации объявляет, что функция выполняется при получении HTTP-запроса. Выходная привязка объявляет, что ответ отправляется в виде HTTP-ответа.
В разделе Сведения о шаблоне в поле Новая функция введите DriveGearTemperatureService. Оставьте для параметра Уровень авторизации значение Функция и затем нажмите кнопку Создать, чтобы создать функцию. Откроется панель "Обзор" для функции DriveGearTemperatureService.
В меню "Функция" выберите пункт Код и тестирование. Откроется редактор кода с содержимым файла кода run.ps1. Следующий фрагмент содержит код по умолчанию, который автоматически создается шаблоном.
using namespace System.Net # Input bindings are passed in via param block. param($Request, $TriggerMetadata) # Write to the Azure Functions log stream. Write-Host "PowerShell HTTP trigger function processed a request." # Interact with query parameters or the body of the request. $name = $Request.Query.Name if (-not $name) { $name = $Request.Body.Name } $body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response." if ($name) { $body = "Hello, $name. This HTTP triggered function executed successfully." } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = $body })
Эта функция ожидает передачи имени или через строку HTTP-запроса, или в самом тексте запроса. Функции HTTP должны создавать ответ путем записи в выходную привязку, для чего в PowerShell служит командлет
Push-OutputBinding
. Функция возвращает сообщение Hello, $name, составляя его на основе полученного в запросе имени.Чтобы просмотреть конфигурацию функции, из раскрывающегося меню "Источник" выберите файл function.json, содержимое которого выглядит примерно так:
{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "direction": "in", "name": "Request", "methods": [ "get", "post" ] }, { "type": "http", "direction": "out", "name": "Response" } ] }
Такая конфигурация означает, что функция выполняется при получении HTTP-запроса. Выходная привязка объявляет, что ответ отправляется в виде HTTP-ответа.
Проверка функции
Совет
Средство командной строки cURL можно использовать для отправки и получения файлов. Оно входит в состав Linux, macOS и Windows 10, а также доступно для большинства других операционных систем. cURL поддерживает множество протоколов, в том числе HTTP, HTTPS, FTP, FTPS, SFTP, LDAP, TELNET, SMTP, POP3 и другие. Дополнительные сведения см. по следующим ссылкам.
Чтобы протестировать функцию, отправьте HTTP-запрос на URL-адрес функции, запустив cURL в командной строке.
Разверните фрейм Журналы в нижней части панели функции для триггеров. Выберите Журналы файловой системы в раскрывающемся списке в верхней части кадра журналов. Кадр журнала должен начать каждую минуту принимать уведомления о трассировке.
Чтобы найти URL-адрес конечной точки функции, на панели команд выберите Получить URL-адрес функции, как показано на следующем рисунке. Сохраните эту ссылку, выбрав значок Копировать в буфер обмена в конце URL-адреса. Сохраните эту ссылку в Блокноте или аналогичном приложении для последующего использования.
Откройте командную строку и запустите cURL, чтобы отправить HTTP-запрос на URL-адрес функции. Имейте в виду использование URL-адреса, скопированного на предыдущем шаге.
curl "<your-https-url>"
Совет
Возможно, потребуется упаковать URL-адрес в кавычки, чтобы избежать проблем с специальными символами в URL-адресе.
Если вы находитесь в Windows, выполните командуcURL
из командной строки. PowerShell имеет команду curl , но это псевдоним для Invoke-WebRequest, который не совпадаетcURL
с .Ответ должен выглядеть следующим образом.
This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response.
Теперь передайте имя в запросе. Для этого необходимо добавить параметр строки запроса с именем
name
URL-адреса. В следующем примере добавляется параметрname=Azure
строки запроса.curl "<your-https-url>&name=Azure"
Ответ должен выглядеть следующим образом.
Hello, Azure. This HTTP triggered function executed successfully.
Функция успешно выполнена и вернула имя, переданное в запросе.
Защита триггеров HTTP
Триггеры HTTP позволяют с помощью ключей API блокировать вызовы от неизвестных объектов, требуя наличие ключа в каждом запросе. При создании функции нужно выбрать уровень авторизации. По умолчанию для уровня задано значение Function, для которого требуется ключ API для конкретной функции. Кроме того, администратор может использовать глобальный главный ключ или анонимный, чтобы указать, что ключ не требуется. Уровень авторизации можно изменить и после создания функции, открыв ее свойства.
При создании этой функции вы указали параметр Функция. Это значит, что при отправке HTTP-запроса нужно предоставить ключ. Его можно отправить как параметр строки запроса с именем code
. Или используйте предпочтительный метод и передайте его в качестве заголовка HTTP с именем x-functions-key
.
Чтобы найти ключи функции, откройте меню "Код + тест ", выбрав имя функции (например, HttpTriger1) на вкладке "Функции " в меню "Обзор ". Затем перейдите на вкладку "Ключи функций".
По умолчанию значение ключа функции скрыто. Отображение значения ключа функции по умолчанию, выбрав "Показать значение". Скопируйте содержимое поля "Значение " в буфер обмена, а затем сохраните этот ключ в Блокноте или аналогичное приложение для последующего использования.
Чтобы проверить функцию с помощью ключа функции, откройте командную строку и запустите cURL, чтобы отправить HTTP-запрос в URL-адрес функции. Замените
<your-function-key>
сохраненным значением ключа функции и замените<your-https-url>
URL-адрес функции.curl --header "Content-Type: application/json" --header "x-functions-key: <your-function-key>" --request POST --data "{\"name\": \"Azure Function\"}" <your-https-url>
Убедитесь, что команда cURL имеет следующие значения:
- Добавляется значение заголовка
Content-Type
типаapplication/json
. - Ключ функции передается как значение заголовка
x-functions-key
. - Используется запрос
POST
. - Передана функция Azure с URL-адресом для функции.
- Добавляется значение заголовка
Проверьте журналы.
В области Код и тест должен открыться сеанс, отображающий выходные данные файла журнала (убедитесь, что журналы файловой системы выбраны в раскрывающемся списке в верхней части панели Журналы). Файл журнала обновляется с учетом состояния вашего запроса, который должен выглядеть примерно так:
```output
2022-02-16T22:34:10.473 [Information] Executing 'Functions.HttpTrigger1' (Reason='This function was programmatically called via the host APIs.', Id=4f503b35-b944-455e-ba02-5205f9e8b47a)
2022-02-16T22:34:10.539 [Information] JavaScript HTTP trigger function processed a request.
2022-02-16T22:34:10.562 [Information] Executed 'Functions.HttpTrigger1' (Succeeded, Id=4f503b35-b944-455e-ba02-5205f9e8b47a, Duration=114ms)
```
```output
2022-02-16T21:07:11.340 [Information] INFORMATION: PowerShell HTTP trigger function processed a request.
2022-02-16T21:07:11.449 [Information] Executed 'Functions.DriveGearTemperatureService' (Succeeded, Id=25e2edc3-542f-4629-a152-cf9ed99680d8, Duration=1164ms)
```
Добавление бизнес-логики в функцию
Добавим в функцию логику, которая проверяет полученные показания температуры и присваивает состояние каждому результату.
Наша функция ожидает на вход массив с показаниями температуры. Следующий фрагмент JSON является примером текста запроса, который мы отправим в нашу функцию. Имя массива может немного отличаться для JavaScript или PowerShell, но каждая запись в массиве имеет идентификатор, метку времени и температуру.
{
"Readings": [
{
"driveGearId": 1,
"timestamp": 1534263995,
"temperature": 23
},
{
"driveGearId": 3,
"timestamp": 1534264048,
"temperature": 45
},
{
"driveGearId": 18,
"timestamp": 1534264050,
"temperature": 55
}
]
}
Замените код по умолчанию в нашей функции следующим кодом, реализующим нашу бизнес-логику.
В области функции HttpTrigger1 откройте файл index.js и замените его приведенным ниже кодом. После внесения этого изменения на панели команд нажмите кнопку Сохранить, чтобы сохранить обновления в файле.
module.exports = function (context, req) {
context.log('Drive Gear Temperature Service triggered');
if (req.body && req.body.readings) {
req.body.readings.forEach(function(reading) {
if(reading.temperature<=25) {
reading.status = 'OK';
} else if (reading.temperature<=50) {
reading.status = 'CAUTION';
} else {
reading.status = 'DANGER'
}
context.log('Reading is ' + reading.status);
});
context.res = {
// status: 200, /* Defaults to 200 */
body: {
"readings": req.body.readings
}
};
}
else {
context.res = {
status: 400,
body: "Please send an array of readings in the request body"
};
}
context.done();
};
Мы добавили очень простую логику. Мы проходим через массив и задаем состояние ОК, ОСТОРОЖНО или ОПАСНО в зависимости от значения поля "Температура". Обновленный массив показаний со значениями состояния возвращается обратно.
Обратите внимание на операторы Log
, которые можно увидеть, развернув область Журналы в нижней части панели. При выполнении функции эти инструкции добавляют сообщения в окно журналов.
Тестирование бизнес-логики
Мы будем использовать функцию Тест/Запуск на странице Разработка>Код и тестирование для тестирования функции.
На вкладке "Код и тест" выберите "Тест и запуск". На вкладке Входные данные замените содержимое текстового поля Текст приведенными ниже кодом, чтобы создать пример запроса.
{ "readings": [ { "driveGearId": 1, "timestamp": 1534263995, "temperature": 23 }, { "driveGearId": 3, "timestamp": 1534264048, "temperature": 45 }, { "driveGearId": 18, "timestamp": 1534264050, "temperature": 55 } ] }
Откройте файл run.ps1 и замените его содержимое приведенным ниже кодом. После внесения этого изменения на панели команд нажмите кнопку Сохранить, чтобы сохранить обновления в файле.
using namespace System.Net
param($Request, $TriggerMetadata)
Write-Host "Drive Gear Temperature Service triggered"
$readings = $Request.Body.Readings
if ($readings) {
foreach ($reading in $readings) {
if ($reading.temperature -le 25) {
$reading.Status = "OK"
}
elseif ($reading.temperature -le 50) {
$reading.Status = "CAUTION"
}
else {
$reading.Status = "DANGER"
}
Write-Host "Reading is $($reading.Status)"
}
$status = [HttpStatusCode]::OK
$body = $readings
}
else {
$status = [HttpStatusCode]::BadRequest
$body = "Please send an array of readings in the request body"
}
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $status
Body = $body
})
Мы добавили очень простую логику. Мы проходим через массив и задаем состояние ОК, ОСТОРОЖНО или ОПАСНО в зависимости от значения поля "Температура". Обновленный массив показаний со значениями состояния возвращается обратно.
Обратите внимание на вызовы командлета Write-Host
. При выполнении функции эти инструкции добавляют сообщения в окно журналов.
Тестирование бизнес-логики
Мы будем использовать функцию Тест/Запуск на странице Разработка>Код и тестирование для тестирования функции.
На вкладке "Код и тест" выберите "Тест и запуск". На вкладке Входные данные замените содержимое текстового поля Текст приведенными ниже кодом, чтобы создать пример запроса.
{ "Readings": [ { "driveGearId": 1, "timestamp": 1534263995, "temperature": 23 }, { "driveGearId": 3, "timestamp": 1534264048, "temperature": 45 }, { "driveGearId": 18, "timestamp": 1534264050, "temperature": 55 } ] }
Выберите Выполнить. На вкладке Выходные данные отображается код отклика HTTP (200 OK) и содержимое. Чтобы просмотреть сообщения журнала, откройте вкладку "Журналы" в нижнем всплывающем меню панели (если она еще не открыта). На следующем рисунке показан пример ответа в области вывода и сообщений в области Журналы.
На вкладке "Выходные данные " показано, что поле состояния было правильно добавлено в каждое из считываемых значений.
В меню разработчика слева выберите "Монитор ", чтобы увидеть, что запрос был зарегистрирован в Application Insights. Для функции появится панель Мониторинг.
Вкладка "Вызовы" на панели отображает трассировки вызовов для каждого вызова функции. Выберите значение Date(UTC) для одного из вызовов и просмотрите сведения о выполнении функции.