Spring Cloud-functie in Azure

Dit artikel helpt u bij het gebruik van Spring Cloud Functions om een Java-functie te ontwikkelen en deze te publiceren naar Azure Functions. Wanneer u klaar bent, wordt uw functiecode uitgevoerd in het Verbruiksabonnement in Azure en kan deze worden geactiveerd met behulp van een HTTP-aanvraag.

Als u geen Azure-abonnement hebt, maakt u een gratis account voordat u begint.

Vereisten

Als u functies wilt ontwikkelen met behulp van Java, moet het volgende zijn geïnstalleerd:

Belangrijk

  1. U moet de JAVA_HOME omgevingsvariabele instellen op de installatielocatie van de JDK om deze quickstart te voltooien.
  2. Zorg ervoor dat uw kernhulpprogrammaversie ten minste 4.0.5455 is.

Wat we gaan bouwen

We gaan een klassieke 'Hallo wereld'-functie bouwen die wordt uitgevoerd op Azure Functions en is geconfigureerd met Spring Cloud Function.

De functie ontvangt een User JSON-object dat een gebruikersnaam bevat en stuurt een Greeting object terug, dat het welkomstbericht voor die gebruiker bevat.

Het project is beschikbaar in de Spring Cloud-functie in Azure-voorbeeld van de opslagplaats azure-function-java-worker op GitHub. U kunt dat voorbeeld rechtstreeks gebruiken als u het uiteindelijke werk wilt zien dat in deze quickstart wordt beschreven.

Een nieuw Maven-project maken

We gaan een leeg Maven-project maken en configureren met Spring Cloud Function en Azure Functions.

Maak in een lege map een nieuw pom.xml-bestand en kopieer/plak de inhoud uit het pom.xml-bestand van het voorbeeldproject.

Notitie

Dit bestand maakt gebruik van Maven-afhankelijkheden van zowel Spring Boot als Spring Cloud Function en wordt gebruikt om de Maven-invoegtoepassingen van Spring Boot en Azure Functions te configureren.

U moet enkele eigenschappen voor uw toepassing aanpassen:

  • <functionAppName> is de naam van uw Azure-functie
  • <functionAppRegion> is de naam van de Azure-regio waar de functie wordt geïmplementeerd
  • <functionResourceGroup> is de naam van de Azure-resourcegroep die u gebruikt

Wijzig deze eigenschappen direct boven aan het pom.xml-bestand , zoals wordt weergegeven in het volgende voorbeeld:

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

Maak een src/main/resources-map en voeg de volgende Azure Functions-configuratiebestanden eraan toe.

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

Domeinobjecten maken

In Azure Functions kunt u objecten ontvangen en verzenden in JSON-indeling. We gaan nu onze User en Greeting objecten maken, die ons domeinmodel vertegenwoordigen. U kunt complexere objecten maken, met meer eigenschappen, als u deze quickstart wilt aanpassen en deze interessanter wilt maken.

Maak de map src/main/java/com/example/model en voeg de volgende twee bestanden toe:

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

De Spring Boot-toepassing maken

Deze toepassing beheert alle bedrijfslogica en heeft toegang tot het volledige Spring Boot-ecosysteem. Deze mogelijkheid biedt u twee belangrijke voordelen ten opzichte van een standaard Azure-functie:

  • Het is niet afhankelijk van de Azure Functions-API's, zodat u deze eenvoudig kunt overzetten naar andere systemen. U kunt deze bijvoorbeeld opnieuw gebruiken in een normale Spring Boot-toepassing.
  • U kunt alle @Enable aantekeningen van Spring Boot gebruiken om nieuwe functies toe te voegen.

Maak in de map src/main/java/com/example het volgende bestand. Dit is een normale Spring Boot-toepassing:

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

Maak nu het volgende bestand in de map src/main/java/com/example/hello . Deze code bevat een Spring Boot-onderdeel dat de functie vertegenwoordigt die we willen uitvoeren:

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

Notitie

De functie Hello is heel specifiek:

  • Het is een java.util.function.Function. Het bevat de bedrijfslogica en maakt gebruik van een standaard Java-API om het ene object te transformeren in een ander object.
  • Omdat het de @Component aantekening heeft, is het een Spring Bean en is de naam standaard hetzelfde als de klasse, maar begint met een kleine letter: hello. Het volgen van deze naamconventie is belangrijk als u andere functies in uw toepassing wilt maken. De naam moet overeenkomen met de Azure Functions-naam die we in de volgende sectie gaan maken.

De Azure-functie maken

Om te profiteren van de volledige Azure Functions-API, codeert u nu een Azure-functie die de uitvoering delegeert naar de Spring Cloud-functie die in de vorige stap is gemaakt.

Maak in de map src/main/java/com/example/hello het volgende Azure Function-klassebestand:

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

Deze Java-klasse is een Azure-functie, met de volgende interessante functies:

  • De klas heeft de @Component aantekening, dus het is een Spring Bean.
  • De naam van de functie, zoals gedefinieerd door de @FunctionName("hello") aantekening, is hello.
  • De klasse implementeert een echte Azure-functie, zodat u hier de volledige Azure Functions-API kunt gebruiken.

Eenheidstests toevoegen

Deze stap is optioneel, maar wordt aanbevolen om te controleren of de toepassing correct werkt.

Maak een src/test/java/com/example-map en voeg de volgende JUnit-tests toe:

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

U kunt nu uw Azure-functie testen met Maven:

mvn clean test

De functie lokaal uitvoeren

Voordat u uw toepassing implementeert in Azure Function, moet u deze eerst lokaal testen.

Eerst moet u uw toepassing inpakken in een jar-bestand:

mvn package

Nu de toepassing is verpakt, kunt u deze uitvoeren met behulp van de azure-functions Maven-invoegtoepassing:

mvn azure-functions:run

De Azure-functie moet nu beschikbaar zijn op uw localhost met behulp van poort 7071. U kunt de functie testen door een POST-aanvraag te verzenden, met een User-object in JSON-indeling. Bijvoorbeeld met behulp van cURL:

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

U krijgt van de functie een Greeting-object als antwoord (ook weer in JSON-indeling):

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

Hier volgt een schermopname van de cURL-aanvraag boven aan het scherm en de lokale Azure-functie onderaan:

Azure Function running locally

Fouten in de functie lokaal opsporen

In de volgende secties wordt beschreven hoe u fouten in de functie kunt opsporen.

Fouten opsporen met Intellij IDEA

Open het project in Intellij IDEA en maak vervolgens een externe JVM-uitvoeringsconfiguratie voor foutopsporing om deze toe te voegen. Zie Zelfstudie: Externe foutopsporing voor meer informatie.

Create a Remote JVM Debug run configuration

Voer de toepassing uit met de volgende opdracht:

mvn azure-functions:run -DenableDebug

Wanneer de toepassing wordt gestart, ziet u de volgende uitvoer:

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

Projectopsporing starten in IntelliJ IDEA. U ziet de volgende uitvoer:

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

Markeer de onderbrekingspunten die u wilt opsporen. De Intellij IDEA voert de foutopsporingsmodus in na het verzenden van een aanvraag.

Fouten opsporen met Visual Studio Code

Open het project in Visual Studio Code en configureer vervolgens de volgende inhoud van het launch.json-bestand :

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

Voer de toepassing uit met de volgende opdracht:

mvn azure-functions:run -DenableDebug

Wanneer de toepassing wordt gestart, ziet u de volgende uitvoer:

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

Start projectopsporing in Visual Studio Code en markeer vervolgens de onderbrekingspunten die u wilt opsporen. Visual Studio Code voert de foutopsporingsmodus in nadat een aanvraag is verzonden. Zie Uitvoeren en fouten opsporen in Java voor meer informatie.

De functie implementeren in Azure Functions

Nu gaat u de Azure-functie publiceren naar productie. Houd er rekening mee dat de <functionAppName>eigenschappen <functionAppRegion>en <functionResourceGroup> eigenschappen die u hebt gedefinieerd in uw pom.xml-bestand , worden gebruikt om uw functie te configureren.

Notitie

De Maven-invoegtoepassing moet worden geverifieerd met Azure. Als u Azure CLI hebt geïnstalleerd, gebruikt az login u deze voordat u doorgaat. Zie Verificatie in de opslagplaats azure-maven-plugins voor meer verificatieopties.

Voer Maven uit om uw functie automatisch te implementeren:

mvn azure-functions:deploy

Ga nu naar Azure Portal om de gemaakte Function App te zoeken.

Selecteer de functie:

  • In het overzicht van functies ziet u de URL van de functie.
  • Als u de actieve functie wilt controleren, selecteert u Logboekstreaming in het navigatiemenu.

Net zoals u in de vorige sectie hebt gedaan, gebruikt u cURL voor toegang tot de actieve functie, zoals wordt weergegeven in het volgende voorbeeld. Zorg ervoor dat u de naam van uw echte functie vervangt your-function-name .

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

Als het goed is, krijgt u van de functie een Greeting-object als antwoord (ook weer in JSON-indeling), net als in de vorige sectie:

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

U hebt nu een Spring Cloud Function die wordt uitgevoerd in Azure Functions. Zie de volgende bronnen voor meer informatie en voorbeelden van Spring Cloud-functies:

Volgende stappen

Voor meer informatie over Spring en Azure gaat u door naar het documentatiecentrum van Spring op Azure.