Функция Spring Cloud в Azure

В этой статье описывается, как с помощью функций Spring Cloud разработать функцию Java и опубликовать ее в Функциях Azure. После выполнения действий, описанных в этой статье, код функции будет выполняться в Azure в Плане потребления и может запускаться с помощью HTTP-запроса.

Если у вас еще нет подписки Azure, создайте бесплатную учетную запись Azure, прежде чем начать работу.

Необходимые компоненты

Для разработки функций с помощью Java, должны быть установлены следующие компоненты:

Важно!

  1. Чтобы завершить работу с этим кратким руководством, необходимо задать JAVA_HOME переменную среды в расположении установки JDK.
  2. Убедитесь, что версия основных средств не менее 4.0.5455.

Что мы будем создавать

Мы создадим классическую функцию Hello, World, которая работает на Функции Azure и настроена с помощью функции Spring Cloud.

Функция получает User объект JSON, содержащий имя пользователя, и отправляет Greeting объект обратно, содержащий приветственное сообщение пользователю.

Проект доступен в примере функции Spring Cloud в Azure из репозитория azure-function-java-worker на сайте GitHub. Этот пример можно использовать непосредственно, если вы хотите просмотреть окончательную работу, описанную в этом кратком руководстве.

Создание нового проекта Maven

Мы создадим пустой проект Maven и настроим его с помощью Spring Cloud Function и Функций Azure.

В пустой папке создайте файл pom.xml, а затем скопируйте и содержимое из нашего примера проекта и вставьте его в файл pom.xml.

Примечание.

В этом файле используются зависимости Maven от Spring Boot и функции Spring Cloud, а также настраиваются плагины Maven для Spring Boot и Функций Azure.

Необходимо настроить несколько свойств для приложения:

  • <functionAppName> — это имя функции Azure.
  • <functionAppRegion> — это имя региона Azure, в котором развернута функция.
  • <functionResourceGroup> — имя используемой группы ресурсов Azure.

Эти свойства можно изменить прямо в файле pom.xml, в самом его начале, как показано в следующем примере:

    <properties>
        <java.version>11</java.version>

        <!-- Spring Boot start class. WARNING: correct class must be set -->
        <start-class>com.example.DemoApplication</start-class>

        <!-- customize those properties. WARNING: the functionAppName should be unique across Azure -->
        <azure.functions.maven.plugin.version>1.29.0</azure.functions.maven.plugin.version>
        <functionResourceGroup>my-spring-function-resource-group</functionResourceGroup>
        <functionAppServicePlanName>my-spring-function-service-plan</functionAppServicePlanName>
        <functionAppName>my-spring-function</functionAppName>
        <functionPricingTier>Y1</functionPricingTier>
        <functionAppRegion>eastus</functionAppRegion>
    </properties>

Создание файлов конфигурации в Azure

Создайте папку src/main/resources и добавьте в нее следующие Функции Azure файлы конфигурации.

host.json

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.2.0)"
  },
  "functionTimeout": "00:10:00"
}

local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "java",
    "FUNCTIONS_EXTENSION_VERSION": "~4",
    "AzureWebJobsDashboard": ""
  }
}

Создание объектов домена

Функции Azure могут получать и отправлять объекты в формате JSON. Сейчас мы создадим объекты User и Greeting, которые представляют модель предметной области. Вы можете создать более сложные объекты с дополнительными свойствами, если хотите настроить пример из этого руководства и сделать его более интересным.

Создайте папку src/main/java/com/example/model и добавьте в нее следующие два файла.

User. Java:

package com.example.model;

public class User {

    private String name;

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Greeting.java:

package com.example.model;

public class Greeting {

    private String message;

    public Greeting() {
    }

    public Greeting(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

Создание приложения Spring Boot

Это приложение управляет всей бизнес-логикой и имеет доступ к полной экосистеме Spring Boot. Эта возможность предоставляет два основных преимущества по сравнению с использованием стандартной Функции Azure.

  • Отсутствует зависимость от API Функций Azure, что позволяет легко перенести функцию в другие системы. Например, ее можно использовать в обычном приложении Spring Boot.
  • Вы можете использовать любые аннотации @Enable из Spring Boot, чтобы добавлять новые возможности.

В папке src/main/java/com/example создайте следующий файл, который представляет собой обычное приложение Spring Boot.

DemoApplication.java:

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Теперь создайте следующий файл в папке src/main/java/com/example/hello . Этот код содержит компонент Spring Boot, представляющий функцию, которую мы хотим запустить:

Hello.java:

package com.example.hello;

import com.example.model.*;
import org.springframework.stereotype.Component;
import java.util.function.Function;

@Component
public class Hello implements Function<User, Greeting> {

    @Override
    public Greeting apply(User user) {
        return new Greeting("Hello, " + user.getName() + "!\n");
    }
}

Примечание.

Функция Hello довольно специфична:

  • Это java.util.function.Function. Она содержит бизнес-логику и использует стандартный API Java для преобразования одного объекта в другой.
  • Так как у этой функции есть аннотация @Component, она представляет собой компонент Spring Bean и по умолчанию ее имя будет совпадать с именем класса, но начинаться с символа в нижнем регистре (hello). Соблюдение этого соглашения об именовании очень важно, если вы будете создавать в приложении другие функции. Это имя должно совпадать с именем Функций Azure, которые мы создадим в следующем разделе.

Создание функции Azure

Чтобы воспользоваться полным Функции Azure API, теперь мы кодируем функцию Azure, которая делегирует выполнение функции Spring Cloud, созданной на предыдущем шаге.

В папке src/main/java/com/example/hello создайте следующий файл класса функций Azure:

HelloHandler.java:

package com.example.hello;

import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import com.example.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class HelloHandler {

    @Autowired
    private Hello hello;

    @FunctionName("hello")
    public HttpResponseMessage execute(
        @HttpTrigger(name = "request", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<User>> request, ExecutionContext context) {
        User user = request.getBody()
                           .filter(u -> u.getName() != null)
                           .orElseGet(() -> new User(request.getQueryParameters().getOrDefault("name", "world")));
        context.getLogger().info("Greeting user name: " + user.getName());
        return request.createResponseBuilder(HttpStatus.OK)
                      .body(hello.apply(user))
                      .header("Content-Type", "application/json")
                      .build();
    }
}

Этот класс Java представляет собой Функцию Azure со следующими интересными возможностями:

  • Класс имеет заметку @Component , поэтому это Spring Bean.
  • Имя функции (определенное аннотацией @FunctionName("hello")) — hello.
  • Класс реализует реальную функцию Azure, поэтому здесь можно использовать полный Функции Azure API.

Добавить модульные тесты

Этот шаг является необязательным, но мы рекомендуем выполнить его для проверки правильности работы приложения.

Создайте папку src/test/java/com/example и добавьте в нее следующие модульные тесты JUnit:

HelloTest.java:

package com.example;

import com.example.hello.Hello;
import com.example.model.Greeting;
import com.example.model.User;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class HelloTest {

    @Test
    public void test() {
        Greeting result = new Hello().apply(new User("foo"));
        assertThat(result.getMessage()).isEqualTo("Hello, foo!\n");
    }
}

Теперь можно протестировать функцию Azure с помощью Maven:

mvn clean test

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

Прежде чем развертывать приложение в Функции Azure, протестируйте его локально.

Сначала упакуйте приложение в JAR-файл:

mvn package

Теперь, когда приложение упаковано, вы можете запустить его с помощью подключаемого модуля Maven azure-functions:

mvn azure-functions:run

Функция Azure должна быть доступна на локальном узле, использующем порт 7071. Чтобы протестировать функцию, можете отправить ей запрос POST с объектом User в формате JSON. Например, это можно сделать с помощью cURL:

curl -X POST http://localhost:7071/api/hello -d "{\"name\":\"Azure\"}"

Функция должна отправить ответ с объектом Greeting в том же формате JSON:

{
  "message": "Hello, Azure!\n"
}

Ниже приведен снимок экрана, в верхней части которого показан запрос cURL, а в нижней — локальная Функция Azure:

Azure Function running locally

Локальная отладка Функции

В следующих разделах описывается процесс отладки функции.

Отладка с использованием IntelliJ IDEA

Откройте проект в IntelliJ IDEA и создайте конфигурацию выполнения Удаленная отладка виртуальной машины Java для подключения. Дополнительные сведения см. в руководстве по удаленной отладке.

Create a Remote JVM Debug run configuration

Запустите приложение, выполнив следующую команду:

mvn azure-functions:run -DenableDebug

При запуске приложения вы увидите следующие выходные данные:

Worker process started and initialized.
Listening for transport dt_socket at address: 5005

Запустите отладку проекта в IntelliJ IDEA. Вы увидите такой результат:

Connected to the target VM, address: 'localhost:5005', transport: 'socket'

Отметьте точки останова, которые вы хотите отладить. Intellij IDEA войдет в режим отладки после отправки запроса.

Отладка с помощью Visual Studio Code

Откройте проект в Visual Studio Code и поместите следующее содержимое в файл launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "java",
            "name": "Attach to Remote Program",
            "request": "attach",
            "hostName": "127.0.0.1",
            "port": 5005
        }
    ]
}

Запустите приложение, выполнив следующую команду:

mvn azure-functions:run -DenableDebug

При запуске приложения вы увидите следующие выходные данные:

Worker process started and initialized.
Listening for transport dt_socket at address: 5005

Запустите отладку проекта в Visual Studio Code и установите точки останова, которые вы хотите отладить. Visual Studio Code войдет в режим отладки после отправки запроса. Дополнительные сведения см. на странице, посвященной выполнению и отладке Java.

Развертывание Функции в Функциях Azure

Теперь вы собираетесь опубликовать функцию Azure в рабочей среде. Помните, что <functionAppName><functionAppRegion>для настройки функции используются свойства, <functionResourceGroup> определенные в файле pom.xml.

Примечание.

Подключаемый модуль Maven должен пройти проверку подлинности в Azure. Если у вас установлен интерфейс командной строки Azure, выполните az login, прежде чем продолжать. Другие варианты проверки подлинности вы найдете в разделе Authentication (Аутентификация) репозитория azure-maven-plugins.

Запустите Maven, чтобы автоматически развернуть функцию:

mvn azure-functions:deploy

Теперь перейдите на портал Azure, чтобы найти созданный объект Function App.

Выберите функцию.

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

Теперь, как и в предыдущем разделе, с помощью cURL создайте запрос к запущенной функции, как показано в следующем примере. Не забудьте заменить значение your-function-name именем реальной функции.

curl https://your-function-name.azurewebsites.net/api/hello -d "{\"name\":\"Azure\"}"

Как и в предыдущем разделе, Функция должна отправить ответ с объектом Greeting в том же формате JSON:

{
  "message": "Hello, Azure!\n"
}

Поздравляем! У вас есть функция Spring Cloud, выполняемая в Функциях Azure. Дополнительные сведения и примеры функций Spring Cloud см. в следующих ресурсах:

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

Дополнительные сведения о Spring и Azure см. в центре документации об использовании Spring в Azure.