Проверяйте API в пакетном режиме и выпускайте приложение в производственную среду только после автоматической проверки.

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

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

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

В этой статье речь пойдет о Release Gates. Ворота выпуска могут обеспечить дополнительный уровень проверки, будь то проверка на соответствие или проверка функциональности или готовности приложения, что может помочь уменьшить количество проблем после нашего развертывания.

Сценарии

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

Помимо вызова API для систем, он также может включать вызов внешних API, например, проверку состояния внешних конечных точек, проверку соответствия и т. д.

Под затвором доступно несколько вариантов, как показано на диаграмме ниже.

Обычно используется проверка соответствия политике Azure, поскольку это позволяет клиентам развертывать рабочую нагрузку в среде, соответствующей стандартам организации. Мы также можем вызывать API через универсальное соединение или Функции Azure. Наконец, запросы к оповещениям и рабочим элементам Azure Monitor также имеют решающее значение, чтобы обеспечить соответствие выпуска в новой среде определенным стандартам. Вы можете получить более подробную информацию о выпуске здесь: https://docs.microsoft.com/en-us/azure/devops/pipelines/release/approvals/gates?view=azure-devops

Определить универсальное соединение для REST API очень просто. Мы можем просто создать сервисное соединение в настройках проекта и указать URL-адрес сервера и данные аутентификации.

Это работает для нескольких API. Мы можем определить их один за другим. Как насчет 20, 30 и более API?

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

Вернемся к сервисному подключению. Как показано на диаграмме, фактически нам нужно определить конечные точки одну за другой, что невозможно, если мы вызываем более 10 конечных точек. Тогда возникает вопрос, есть ли способ организовать все вызовы API и агрегировать ответы, чтобы они служили воротами для выпуска?

Решения

Функции Azure хорошо известны как бессерверные вычисления для Функции как услуга, которые часто используются в рабочей нагрузке микрослужб. Обычно он не имеет гражданства и недолговечен. Устойчивые функции Azure, с другой стороны, предназначены для обработки задания с отслеживанием состояния в дополнение к преимуществам функций Azure. В частности, Azure Durable Functions отлично справляется с ролью оркестратора для параллельного выполнения задач или в определенной последовательности. Существует множество шаблонов приложений для устойчивых функций Azure для различных вариантов использования, которые описаны здесь: https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview?tabs=csharp.

В этом контексте мы можем использовать шаблон Fan out/fan в этом случае использования. Идея проста. Мы вызываем оркестратор, который затем вызывает список REST API и, наконец, агрегирует результаты и возвращает их в качестве выходных данных.

Давайте посмотрим, как это работает в деталях.

Оркестратор устойчивых функций Azure

Начну с шаблона. Используя VS Code или Visual Studio, я могу выбрать шаблон функций Azure, и в этом случае я выбрал Оркестровка устойчивых функций в качестве отправной точки. Создается следующий шаблон.

Он сгенерирует 3 функции, а именно «DurableFunctionsOrchestration», «DurableFunctionsOrchestration_Hello» и «DurableFunctionsOrchestration_HttpStart». Давайте разберемся в них снизу.

«DurableFunctionsOrchestration_HttpStart» определяется как точка входа для рабочего процесса, выступающая в качестве надежного клиента. Как показано в строке 27, он использует HTTP-триггер. Это означает, что он примет HTTP GET или HTTP Post и запустит поток согласования. Конечно, в зависимости от варианта использования мы определяем и другие триггеры, такие как триггер таймера, триггер служебной шины Azure и т. д. Вот список доступных привязок, и вы можете использовать поддерживаемую привязку для триггера.



В этом примере я буду использовать триггер HTTP. Его легко вызвать, и этот HTTP-триггер вернет сведения об оркестровке в виде HTTP-ответа, такие как статус оркестровки, выходные данные и т. д., что необходимо в данном случае.

Перейдем к «DurableFunctionsOrchestration». Как следует из названия, эта функция управляет действиями. Я могу определить, как организованы действия, например, запуск в асинхронном режиме или запуск в последовательном режиме, в зависимости от выходных данных предыдущего действия. В приведенном выше примере, в строках с 10 по 12, он просто запускает последовательное действие, которое выполняет цепочку функций. Это место, где мы создаем один из шести шаблонов, упомянутых выше.

Целевое действие из «DurableFunctionsOrchestration» называется «DurableFunctionsOrchestration_Hello», принимая строку в качестве входных данных. Здесь выполняется вся тяжелая работа.

Вернемся к нашему сценарию. Идея состоит в том, чтобы создать функцию, которая будет выполнять несколько вызовов API для проверки состояния и вывода, а также возвращать результаты обратно в выпускной шлюз Azure Pipeline.

Теперь, когда мы получили представление об устойчивых функциях Azure, давайте посмотрим, как мы можем реализовать их в этом сценарии. Я начну с активности, функций, которые выполняют все тяжелые задачи.

Я назвал его HealthCheck_Executor. В демонстрационных целях я просто выполняю эхо для моего внутреннего API, подтверждая, что возвращенное сообщение совпадает с моим вводом. Единственное дополнительное действие, которое я сделал, — это создание объекта с именем APICheckObject для захвата имени API и его статуса. Помните, что позже я хочу агрегировать все результаты, поэтому сделать 1 или 0 — это простой способ, и в то же время я могу определить, какой API не работает должным образом.

Далее переходим к оркестратору. Первый вопрос, который нужно решить, какой правильный шаблон я должен использовать? Цепочка функций и разветвление/разветвление кажутся жизнеспособными кандидатами.

Я выберу цепочку функций, если API тестируются последовательно, например, второй API зависит от вывода первого API. В моем случае все API-интерфейсы независимы друг от друга, поэтому я выбираю разветвление/разветвление, чтобы распараллелить все выполнение для более короткого времени выполнения.

Затем я верну результат в виде списка объектов в качестве вывода всего процесса.

Последняя часть головоломки — это способ вызвать эту долговременную функцию. Я буду придерживаться HTTP-триггера, но мне нужно еще кое-что. Если я вызову эту долговременную функцию напрямую, она вернет несколько URL-адресов, в основном для того, чтобы мы могли проверить статус или завершить задачу. Шлюз выпуска Azure Pipeline не сможет использовать выходные данные.

Чтобы решить эту проблему, я могу просто создать еще одну функцию Azure с помощью триггера HTTP, чтобы вызвать эту надежную функцию и в то же время агрегировать выходные данные для проверки в Azure DevOps.

Полный исходный код можно найти на GitHub.



Проверка шлюза выпуска Azure Pipeline

Давайте проверим выходные данные функций Azure выше. У меня есть общий успешный вызов, а также соответствующее имя API и его статус.

{
   "totalSuccess":3,
   "details":[
                {"apiName":"test1","apiStatus":1},
                {"apiName":"test2","apiStatus":1},  
                {"apiName":"test3","apiStatus":1}
             ]
}

В Azure Pipeline давайте перейдем к конвейеру выпуска и изменим ворота выпуска. Чтобы добавить Функции Azure в ворота выпуска, мы можем либо выполнить предварительное развертывание, либо после развертывания. В моем случае я пойду на пост-развертывание. Добавить Функции Azure очень просто. Просто нажмите «+ Добавить» в верхнем левом углу под «Gates» и введите URL-адрес функций Azure и ключ функций Azure. Если вы не знаете, где получить ключ, он находится на портале Azure.

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



Вот как выглядят мои релиз-ворота.

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

Диаграмма ниже визуализирует весь поток.

Благодаря этому теперь вы можете проверять API в пакетном режиме и автоматически выпускать приложение в производственную среду только после проверки!