Spring Cloud Function no Azure
Este artigo descreve como usar o Spring Cloud Function para desenvolver uma função Java e publicá-la no Azure Functions. Quando terminar, seu código de função será executado nos Plano de Consumo no Azure e poderá ser disparado usando uma solicitação HTTP.
Pré-requisitos
- Uma assinatura do Azure. Se você não tiver uma assinatura do Azure, crie uma conta gratuita antes de começar.
Para desenvolver funções usando Java, você deve ter o seguinte instalado:
- Java Developer Kit, versão 11
- Apache Maven, versão 3.0 ou superior
- CLI do Azure
- Azure Functions Core Tools versão 4
Importante
- Você precisará definir a variável de ambiente
JAVA_HOME
como local de instalação do JDK para concluir este guia de início rápido. - Sua versão do Core Tools deve ser, pelo menos, 4.0.5455.
O que vamos criar
Vamos criar uma função "Olá, Mundo" clássica que é executada no Azure Functions e configurada com o Spring Cloud Function.
A função recebe um objeto JSON User
que contém um nome de usuário e envia de volta um objeto Greeting
que contém a mensagem de boas-vindas para o usuário.
O projeto está disponível no exemplo Spring Cloud Function no Azure do repositório azure-function-java-worker, no GitHub. Você poderá usar esse exemplo diretamente se quiser ver o trabalho final descrito neste guia de início rápido.
Criar um novo projeto Maven
Vamos criar um projeto Maven vazio e configurá-lo com o Azure Functions e o Spring Cloud Function.
Em uma pasta vazia, crie um arquivo pom.xml e copie e cole o conteúdo do arquivo pom.xml do projeto de exemplo.
Observação
Esse arquivo usa dependências de Maven do Spring Boot e do Spring Cloud Function e configura os plug-ins de Maven do Spring Boot e do Azure Functions.
Você precisará personalizar algumas propriedades do aplicativo:
<functionAppName>
é o nome de sua função do Azure<functionAppRegion>
é o nome da região do Azure em que a função é implantada<functionResourceGroup>
é o nome do grupo de recursos do Azure que você está usando
Altere essas propriedades diretamente no início do arquivo pom.xml, conforme mostrado no seguinte exemplo:
<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>
Criar arquivos de configuração do Azure
Crie uma pasta src/main/resources e adicione os seguintes arquivos de configuração do Azure Functions a ela.
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": ""
}
}
Criar objetos de domínio
O Azure Functions pode receber e enviar objetos no formato JSON.
Agora, vamos criar os objetos User
e Greeting
, que representam o modelo de domínio.
Você pode criar objetos mais complexos, com mais propriedades, se quiser personalizar este guia de início rápido e torná-lo mais interessante para você.
Crie uma pasta src/main/java/com/example/model e adicione os dois arquivos a seguir:
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;
}
}
Criar o aplicativo Spring Boot
Este aplicativo gerencia toda a lógica de negócios e tem acesso a todo o ecossistema do Spring Boot. Essa funcionalidade traz dois benefícios principais em relação a uma função padrão do Azure:
- Ela não depende das APIs do Azure Functions, de modo que pode ser portada facilmente para outros sistemas. Por exemplo, você pode reutilizá-la em um aplicativo Spring Boot normal.
- Use todas as anotações
@Enable
do Spring Boot para adicionar novos recursos.
Na pasta src/main/java/com/example, crie o seguinte arquivo, que é um aplicativo Spring Boot normal:
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);
}
}
Agora crie o seguinte arquivo na pasta src/main/java/com/example/hello. Este código contém um componente Spring Boot, que representa a função que queremos executar:
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");
}
}
Observação
A função Hello
é bastante específica:
- É um
java.util.function.Function
. Ela contém a lógica de negócios e usa uma API Java padrão para transformar um objeto em outro. - Como tem a anotação
@Component
, ela é um Spring Bean e, por padrão, o nome dela é igual ao da classe, mas começa com um caractere em minúsculas,hello
. Será importante seguir essa convenção de nomenclatura se você quiser criar outras funções no aplicativo. O nome precisa corresponder ao nome do Azure Functions que criaremos na próxima seção.
Criar a função do Azure
Para aproveitar toda a API do Azure Functions, agora codificamos uma função do Azure que delega sua execução ao Spring Cloud Function criado na etapa anterior.
Na pasta src/main/java/com/example/hello, crie o seguinte arquivo de classe do Azure Functions:
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();
}
}
Essa classe Java é uma função do Azure, com os seguintes recursos interessantes:
- A classe tem a anotação
@Component
, então é um Spring Bean. - O nome da função, conforme definido pela anotação
@FunctionName("hello")
, éhello
. - A classe implementa uma função real do Azure, assim, você pode usar a API completa do Azure Functions aqui.
Adicionar testes de unidade
Esta etapa é opcional, mas recomendada para validar se o aplicativo funciona corretamente.
Crie uma pasta src/test/java/com/example e adicione os seguintes testes do 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");
}
}
Agora, você pode testar sua função do Azure usando o Maven:
mvn clean test
Executar a função localmente
Antes de implantar seu aplicativo na função do Azure, primeiro vamos testá-lo localmente.
Primeiro, você precisa empacotar o aplicativo em um arquivo Jar:
mvn package
Agora que o aplicativo está empacotado, você pode executá-lo usando o plug-in de Maven azure-functions
:
mvn azure-functions:run
Agora, a função do Azure deve estar disponível no localhost usando a porta 7071. Você pode testar a função enviando uma solicitação POST a ela, com um objeto User
no formato JSON. Por exemplo, usando cURL:
curl -X POST http://localhost:7071/api/hello -d "{\"name\":\"Azure\"}"
Agora, a função deve responder a você com um objeto Greeting
, ainda no formato JSON:
{
"message": "Hello, Azure!\n"
}
Esta é uma captura de tela com a solicitação do cURL na parte superior da tela e a função do Azure local na parte inferior:
Depurar a função localmente
As seções a seguir descrevem como depurar a função.
Depuração com o IntelliJ IDEA
Abra o projeto no IntelliJ IDEA e crie uma configuração de execução de Depuração Remota de JVM para anexá-la. Para obter mais informações, confira Tutorial: Depuração remota.
Execute o aplicativo com o seguinte comando:
mvn azure-functions:run -DenableDebug
Quando o aplicativo for iniciado, este é o resultado que você vê:
Worker process started and initialized.
Listening for transport dt_socket at address: 5005
Inicie a depuração do projeto no IntelliJ IDEA. Você verá esta saída:
Connected to the target VM, address: 'localhost:5005', transport: 'socket'
Marque os pontos de interrupção que deseja depurar. O Intellij IDEA entrará no modo de depuração após enviar uma solicitação.
Depuração com o Visual Studio Code
Abra o projeto no Visual Studio Code e configure o seguinte conteúdo do arquivo launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Attach to Remote Program",
"request": "attach",
"hostName": "127.0.0.1",
"port": 5005
}
]
}
Execute o aplicativo com o seguinte comando:
mvn azure-functions:run -DenableDebug
Quando o aplicativo for iniciado, este é o resultado que você vê:
Worker process started and initialized.
Listening for transport dt_socket at address: 5005
Inicie a depuração do projeto no Visual Studio Code e marque os pontos de interrupção que deseja depurar. Após o envio de uma solicitação, o Visual Studio Code entra no modo de depuração. Para obter mais informações, confira Como executar e depurar o Java.
Implantar a função no Azure Functions
Agora, você publicará a função do Azure em produção. Lembre-se de que as propriedades <functionAppName>
, <functionAppRegion>
e <functionResourceGroup>
que você definiu em pom.xml são usadas para configurar a função.
Observação
O plug-in do Maven precisa ser autenticado no Azure. Se você tiver a CLI do Azure instalada, use az login
antes de continuar.
Para obter mais opções de autenticação, confira Autenticação no repositório azure-maven-plugins.
Execute o Maven para implantar a função automaticamente:
mvn azure-functions:deploy
Agora, acesse o portal do Azure para encontrar o Function App
que foi criado.
Selecione a função:
- Na visão geral da função, observe a URL da função.
- Para verificar sua função em execução, selecione Streaming de log no menu de navegação.
Agora, assim como você fez na seção anterior, use o cURL para acessar a função em execução, conforme mostrado no exemplo a seguir. Substitua your-function-name
pelo nome da função real.
curl https://your-function-name.azurewebsites.net/api/hello -d "{\"name\":\"Azure\"}"
Assim como na seção anterior, a função deve responder a você com um objeto Greeting
, ainda no formato JSON:
{
"message": "Hello, Azure!\n"
}
Parabéns, você tem uma função Spring Cloud em execução no Azure Functions! Para obter mais informações e exemplos de funções do Spring Cloud, consulte os seguintes recursos:
- Blog do Spring Cloud Function
- Documentos de referência do Spring Cloud Function
- Exemplos do Spring Cloud Function
Próximas etapas
Para saber mais sobre o Spring e o Azure, continue no Spring no Centro de Documentação do Azure.