Funkcja Spring Cloud na platformie Azure

W tym artykule opisano proces tworzenia funkcji języka Java i publikowania jej w usłudze Azure Functions przy użyciu funkcji Spring Cloud. Gdy wszystko będzie gotowe, Twój kod funkcji zostanie uruchomiony w planie zużycia na platformie Azure i może być wyzwalany za pomocą żądania HTTP.

Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto.

Wymagania wstępne

Aby opracowywać funkcje przy użyciu języka Java, musisz mieć zainstalowane następujące składniki:

Ważne

  1. Aby ukończyć ten przewodnik Szybki start, należy ustawić zmienną JAVA_HOME środowiskową na lokalizację instalacji zestawu JDK.
  2. Upewnij się, że podstawowa wersja narzędzi to co najmniej 4.0.5455.

Co zamierzamy skompilować

Utworzymy klasyczną funkcję "Hello, World", która działa w usłudze Azure Functions i jest skonfigurowana przy użyciu funkcji Spring Cloud.

Funkcja odbiera User obiekt JSON, który zawiera nazwę użytkownika i wysyła z powrotem Greeting obiekt zawierający komunikat powitalny do tego użytkownika.

Projekt jest dostępny w przykładzie funkcji Spring Cloud na platformie Azurew repozytorium azure-function-java-worker w witrynie GitHub. Możesz użyć tego przykładu bezpośrednio, jeśli chcesz zobaczyć ostateczną pracę opisaną w tym przewodniku Szybki start.

Tworzenie nowego projektu Maven

Utworzymy pusty projekt Maven i skonfigurujemy go za pomocą funkcji Spring Cloud i usługi Azure Functions.

W pustym folderze utwórz nowy plik pom.xml i skopiuj/wklej zawartość z pliku pom.xml przykładowego projektu.

Uwaga

Ten plik używa zależności narzędzia Maven z aplikacji Spring Boot i funkcji Spring Cloud oraz konfiguruje wtyczki aplikacji Spring Boot i usługi Azure Functions w narzędziu Maven.

Musisz dostosować kilka właściwości aplikacji:

  • <functionAppName> jest nazwą funkcji platformy Azure
  • <functionAppRegion> jest nazwą regionu świadczenia usługi Azure, w którym jest wdrażana funkcja
  • <functionResourceGroup> to nazwa używanej grupy zasobów platformy Azure

Zmień te właściwości bezpośrednio w górnej części pliku pom.xml , jak pokazano w poniższym przykładzie:

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

Tworzenie plików konfiguracji platformy Azure

Utwórz folder src/main/resources i dodaj do niego następujące pliki konfiguracji usługi Azure Functions.

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": ""
  }
}

Tworzenie obiektów domeny

Usługa Azure Functions może odbierać i wysyłać obiekty w formacie JSON. Teraz utworzymy nasze User obiekty i Greeting , które reprezentują nasz model domeny. Jeśli chcesz dostosować ten przewodnik Szybki start, aby był dla Ciebie ciekawszy, możesz utworzyć bardziej złożone obiekty z większą liczbą właściwości.

Utwórz folder src/main/java/com/example/model i dodaj następujące dwa pliki:

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

Tworzenie aplikacji Spring Boot

Ta aplikacja zarządza całą logiką biznesową i ma dostęp do pełnego ekosystemu platformy Spring Boot. Ta funkcja zapewnia dwie główne korzyści wynikające ze standardowej funkcji platformy Azure:

  • Nie korzysta ona z interfejsów API usługi Azure Functions, więc można łatwo przenosić ją do innych systemów. Można na przykład ponownie użyć jej w normalnej aplikacji Spring Boot.
  • Aby dodać nowe funkcje, możesz użyć wszystkich @Enable adnotacji z platformy Spring Boot.

W folderze src/main/java/com/example utwórz następujący plik, który jest zwykłą aplikacją 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);
    }
}

Teraz utwórz następujący plik w folderze src/main/java/com/example/hello . Ten kod zawiera składnik Spring Boot reprezentujący funkcję, którą chcemy uruchomić:

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

Uwaga

Funkcja Hello jest dość charakterystyczna:

  • Jest to .java.util.function.Function Zawiera logikę biznesową i używa standardowego interfejsu API języka Java do przekształcania jednego obiektu w inny.
  • Ponieważ zawiera @Component adnotację, jest to Spring Bean, a domyślnie jej nazwa jest taka sama jak klasa, ale zaczyna się od małego znaku: hello. Przestrzeganie tej konwencji nazewnictwa jest ważne, jeśli chcesz utworzyć inne funkcje w aplikacji. Nazwa musi być zgodna z nazwą usługi Azure Functions, która zostanie utworzona w następnej sekcji.

Tworzenie funkcji platformy Azure

Aby skorzystać z pełnego interfejsu API usługi Azure Functions, kodujemy teraz funkcję platformy Azure, która deleguje jego wykonywanie do funkcji Spring Cloud utworzonej w poprzednim kroku.

W folderze src/main/java/com/example/hello utwórz następujący plik klasy funkcji platformy 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();
    }
}

Ta klasa języka Java jest funkcją platformy Azure zawierającą następujące ciekawe funkcje:

  • Klasa ma adnotację @Component , więc jest to Spring Bean.
  • Nazwa funkcji, zgodnie z definicją adnotacji @FunctionName("hello") , to hello.
  • Klasa implementuje rzeczywistą funkcję platformy Azure, dzięki czemu możesz użyć pełnego interfejsu API usługi Azure Functions tutaj.

Dodawanie testów jednostkowych

Ten krok jest opcjonalny, ale zalecany, aby sprawdzić, czy aplikacja działa poprawnie.

Utwórz folder src/test/java/com/example i dodaj następujące testy 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");
    }
}

Teraz możesz przetestować funkcję platformy Azure przy użyciu narzędzia Maven:

mvn clean test

Lokalne uruchamianie funkcji

Zanim wdrożysz aplikację do funkcji platformy Azure, najpierw przetestuj ją lokalnie.

W pierwszej kolejności musisz spakować aplikację do pliku JAR:

mvn package

Po spakowaniu aplikacji możesz uruchomić ją za pomocą wtyczki azure-functions narzędzia Maven:

mvn azure-functions:run

Funkcja platformy Azure powinna być teraz dostępna na hoście lokalnym za pośrednictwem portu 7071. Możesz przetestować funkcję, wysyłając jej żądanie POST z obiektem User w formacie JSON. Na przykład przy użyciu programu cURL:

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

Funkcja powinna odpowiedzieć obiektem Greeting, nadal w formacie JSON:

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

Oto zrzut ekranu przedstawiający żądanie cURL w górnej części ekranu i lokalną funkcję platformy Azure u dołu:

Azure Function running locally

Lokalne debugowanie funkcji

W poniższych sekcjach opisano sposób debugowania funkcji.

Debugowanie przy użyciu środowiska Intellij IDEA

Otwórz projekt w środowisku Intellij IDEA, a następnie utwórz konfigurację uruchamiania zdalnego debugowania JVM w celu dołączenia. Aby uzyskać więcej informacji, zobacz Samouczek: debugowanie zdalne.

Create a Remote JVM Debug run configuration

Uruchom aplikację za pomocą następującego polecenia:

mvn azure-functions:run -DenableDebug

Po uruchomieniu aplikacji zobaczysz następujące dane wyjściowe:

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

Rozpocznij debugowanie projektu w środowisku IntelliJ IDEA. Zobaczysz następujące dane wyjściowe:

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

Oznacz punkty przerwania, które chcesz debugować. Środowisko Intellij IDEA wprowadzi tryb debugowania po wysłaniu żądania.

Debugowanie przy użyciu programu Visual Studio Code

Otwórz projekt w programie Visual Studio Code, a następnie skonfiguruj następującą zawartość pliku launch.json :

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

Uruchom aplikację za pomocą następującego polecenia:

mvn azure-functions:run -DenableDebug

Po uruchomieniu aplikacji zobaczysz następujące dane wyjściowe:

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

Rozpocznij debugowanie projektu w programie Visual Studio Code, a następnie oznacz punkty przerwania, które chcesz debugować. Program Visual Studio Code wprowadzi tryb debugowania po wysłaniu żądania. Aby uzyskać więcej informacji, zobacz Uruchamianie i debugowanie języka Java.

Wdrażanie funkcji w usłudze Azure Functions

Teraz opublikujesz funkcję platformy Azure w środowisku produkcyjnym. Pamiętaj, że <functionAppName>właściwości , <functionAppRegion>i <functionResourceGroup> zdefiniowane w pliku pom.xml są używane do konfigurowania funkcji.

Uwaga

Wtyczka Maven musi uwierzytelniać się za pomocą platformy Azure. Jeśli masz zainstalowany interfejs wiersza polecenia platformy Azure, przed kontynuowaniem użyj polecenia az login . Aby uzyskać więcej opcji uwierzytelniania, zobacz Uwierzytelnianie w repozytorium azure-maven-plugins .

Uruchom narzędzie Maven, aby automatycznie wdrożyć funkcję:

mvn azure-functions:deploy

Teraz przejdź do witryny Azure Portal, aby znaleźć utworzony element Function App.

Wybierz funkcję:

  • Zanotuj adres URL funkcji z jej omówienia.
  • Aby sprawdzić uruchomioną funkcję, wybierz pozycję Rejestrowanie przesyłania strumieniowego w menu nawigacji.

Teraz, podobnie jak w poprzedniej sekcji, użyj narzędzia cURL, aby uzyskać dostęp do uruchomionej funkcji, jak pokazano w poniższym przykładzie. Pamiętaj, aby zastąpić your-function-name rzeczywistą nazwą funkcji.

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

Podobnie jak w poprzedniej sekcji, funkcja powinna odpowiedzieć obiektem Greeting, nadal w formacie JSON:

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

Gratulacje — masz funkcję Spring Cloud działającą w usłudze Azure Functions! Aby uzyskać więcej informacji i przykładów funkcji Spring Cloud, zobacz następujące zasoby:

Następne kroki

Aby dowiedzieć się więcej na temat oprogramowania Spring i platformy Azure, przejdź do centrum dokumentacji dotyczącej oprogramowania Spring na platformie Azure.