Функция Spring Cloud в Azure

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

Предварительные требования

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

Внимание

Задайте для переменной среды JAVA_HOME путь к месту установки JDK, чтобы завершить это краткое руководство.

Убедитесь, что версия основных средств составляет не менее 4.0.5455.

Что вы собираетесь создать

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

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

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

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

Создайте пустой проект Maven и настройте его с помощью функции Spring Cloud и Функции 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.36.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

Чтобы использовать полный API Функции Azure, создайте функцию 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, поэтому здесь можно использовать полный API функций Azure.

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

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

Создайте папку 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 теперь доступна в localhost с помощью порта 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, выполняемая локально

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

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

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

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

Создание конфигурации выполнения

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

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, прежде чем продолжать.

Дополнительные параметры проверки подлинности см. в разделе "Проверка подлинности " в репозитории 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.