Crie sua primeira função durável em Java

O Durable Functions é uma extensão do Azure Functions que permite escrever funções com monitoração de estado em um ambiente sem servidor. A extensão gere o estado, os pontos de verificação e os reinícios por si.

Neste guia de início rápido, você aprenderá a criar e testar um aplicativo "Hello World" Durable Functions em Java. O aplicativo Durable Functions mais básico contém as seguintes três funções:

  • Função Orchestrator - descreve um fluxo de trabalho que orquestra outras funções.
  • Função de atividade - chamada pela função orquestradora, executa trabalho e, opcionalmente, retorna um valor.
  • Função de cliente - uma função normal do Azure que inicia uma função de orquestrador. Este exemplo usa uma função acionada por HTTP.

Este guia de início rápido mostrará como criar este aplicativo "Hello World", que você pode fazer de diferentes maneiras. Use o seletor acima para escolher sua abordagem preferida.

Pré-requisitos

Para concluir este tutorial, precisa de:

  • O Java Developer Kit, versão 8 ou mais recente.

  • Apache Maven, versão 3.0 ou mais recente.

  • Versão mais recente das Ferramentas Principais do Azure Functions.

    • Para o Azure Functions 4.x, são necessárias as Ferramentas Principais v4.0.4915 ou mais recentes.
  • Uma conta de Armazenamento do Azure, que requer que você tenha uma assinatura do Azure.

Se não tiver uma subscrição do Azure, crie uma conta gratuita do Azure antes de começar.

Adicione dependências e plug-ins necessários ao seu projeto

Adicione o seguinte ao seu pom.xml:

<properties>
  <azure.functions.maven.plugin.version>1.18.0</azure.functions.maven.plugin.version>
  <azure.functions.java.library.version>3.0.0</azure.functions.java.library.version>
  <durabletask.azure.functions>1.0.0</durabletask.azure.functions>
  <functionAppName>your-unique-app-name</functionAppName>
</properties>

<dependencies>
  <dependency>
    <groupId>com.microsoft.azure.functions</groupId>
    <artifactId>azure-functions-java-library</artifactId>
    <version>${azure.functions.java.library.version}</version>
  </dependency>
  <dependency>
    <groupId>com.microsoft</groupId>
    <artifactId>durabletask-azure-functions</artifactId>
    <version>${durabletask.azure.functions}</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
    </plugin>
    <plugin>
      <groupId>com.microsoft.azure</groupId>
      <artifactId>azure-functions-maven-plugin</artifactId>
      <version>${azure.functions.maven.plugin.version}</version>
      <configuration>
        <appName>${functionAppName}</appName>
        <resourceGroup>java-functions-group</resourceGroup>
        <appServicePlanName>java-functions-app-service-plan</appServicePlanName>
        <region>westus</region>
        <runtime>
          <os>windows</os>
          <javaVersion>11</javaVersion>
        </runtime>
        <appSettings>
          <property>
            <name>FUNCTIONS_EXTENSION_VERSION</name>
            <value>~4</value>
          </property>
        </appSettings>
      </configuration>
      <executions>
        <execution>
          <id>package-functions</id>
          <goals>
            <goal>package</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <artifactId>maven-clean-plugin</artifactId>
      <version>3.1.0</version>
    </plugin>
  </plugins>
</build>

Adicionar arquivos JSON necessários

Adicione um host.json arquivo ao diretório do projeto. Deve ter um aspeto semelhante ao seguinte:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "DurableTask.AzureStorage": "Warning",
      "DurableTask.Core": "Warning"
    }
  },
  "extensions": {
    "durableTask": {
      "hubName": "JavaTestHub"
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

Nota

É importante observar que apenas o pacote de extensão do Azure Functions v4 atualmente tem o suporte necessário para Durable Functions for Java. O Durable Functions for Java não é suportado na v3 e nos pacotes de extensão anteriores. Para obter mais informações sobre pacotes de extensão, consulte a documentação de pacotes de extensão.

O Durable Functions precisa de um provedor de armazenamento para armazenar o estado de tempo de execução. Adicione um local.settings.json arquivo ao diretório do projeto para configurar o provedor de armazenamento. Para usar o Armazenamento do Azure como provedor, defina o valor de para a cadeia de conexão da sua conta de Armazenamento do AzureWebJobsStorage Azure:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<your storage account connection string>",
    "FUNCTIONS_WORKER_RUNTIME": "java"
  }
}

Crie as suas funções

O código de exemplo abaixo mostra um exemplo simples de cada um:

import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;
import java.util.*;

import com.microsoft.durabletask.*;
import com.microsoft.durabletask.azurefunctions.DurableActivityTrigger;
import com.microsoft.durabletask.azurefunctions.DurableClientContext;
import com.microsoft.durabletask.azurefunctions.DurableClientInput;
import com.microsoft.durabletask.azurefunctions.DurableOrchestrationTrigger;

public class DurableFunctionsSample {
    /**
     * This HTTP-triggered function starts the orchestration.
     */
    @FunctionName("StartOrchestration")
    public HttpResponseMessage startOrchestration(
            @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            @DurableClientInput(name = "durableContext") DurableClientContext durableContext,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        DurableTaskClient client = durableContext.getClient();
        String instanceId = client.scheduleNewOrchestrationInstance("Cities");
        context.getLogger().info("Created new Java orchestration with instance ID = " + instanceId);
        return durableContext.createCheckStatusResponse(request, instanceId);
    }

    /**
     * This is the orchestrator function, which can schedule activity functions, create durable timers,
     * or wait for external events in a way that's completely fault-tolerant.
     */
    @FunctionName("Cities")
    public String citiesOrchestrator(
            @DurableOrchestrationTrigger(name = "taskOrchestrationContext") TaskOrchestrationContext ctx) {
        String result = "";
        result += ctx.callActivity("Capitalize", "Tokyo", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "London", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "Seattle", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "Austin", String.class).await();
        return result;
    }

    /**
     * This is the activity function that gets invoked by the orchestrator function.
     */
    @FunctionName("Capitalize")
    public String capitalize(@DurableActivityTrigger(name = "name") String name, final ExecutionContext context) {
        context.getLogger().info("Capitalizing: " + name);
        return name.toUpperCase();
    }
}

Criar um projeto local com o comando Maven

  1. Execute o seguinte comando para gerar um projeto com as funções básicas de um aplicativo Durable Functions:
mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DarchetypeVersion=1.51 -Dtrigger=durablefunctions
  1. Siga as instruções e forneça as seguintes informações:
Prompt Valor
groupId com.function
artifactId myDurableFunction
Versão 1.0-SNAPSHOT
embalagem com.function
Y Pressione enter para confirmar

Agora você tem um projeto local gerado com as três funções necessárias para um aplicativo básico de Funções Duráveis.

Por favor, verifique se você tem com.microsoft:durabletask-azure-functions como uma dependência em seu pom.xml.

Configurar provedor de armazenamento de back-end

O Durable Functions precisa de um provedor de armazenamento para armazenar o estado de tempo de execução. Você pode configurar para usar o Armazenamento do Azure como o provedor de armazenamento fornecendo local.settings.json a cadeia de conexão da sua conta de Armazenamento do Azure como o valor para AzureWebJobsStorage:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<your storage account connection string>",
    "FUNCTIONS_WORKER_RUNTIME": "java"
  }
}

Criar o seu projeto local

  1. No Visual Studio Code, pressione F1 (ou Ctrl/Cmd+Shift+P) para abrir a paleta de comandos. Na paleta de comandos, procure e selecione Azure Functions: Create New Project....

    Screenshot of create new functions project.

  2. Escolha um local de pasta vazia para seu projeto e escolha Selecionar.

  3. Siga as instruções e forneça as seguintes informações:

    Prompt Valor
    Selecione um idioma Selecione Java.
    Selecione uma versão do Java Escolha Java 8 ou mais recente, a versão Java na qual suas funções são executadas no Azure. Escolha uma versão do Java que você verificou localmente.
    Fornecer um ID de grupo com.function.
    Fornecer um ID de artefato myDurableFunction.
    Fornecer uma versão 1.0-SNAPSHOT.
    Forneça um nome de pacote com.function.
    Fornecer um nome de aplicativo myDurableFunction.
    Selecione a ferramenta de construção para o projeto Java Selecione Maven.
    Selecione como gostaria de abrir o seu projeto Selecione Open in new window.

Agora você tem um projeto com uma função HTTP de exemplo. Você pode remover essa função se desejar, pois adicionaremos as funções básicas de um aplicativo de Funções Duráveis na próxima etapa.

Adicionar funções ao projeto

  1. Na paleta de comandos, procure e selecione Azure Functions: Create Function....

  2. Selecione Change template filter para All.

  3. Siga as instruções e forneça as seguintes informações:

    Prompt Valor
    Selecione um modelo para a sua função DurávelFunçõesOrquestração
    Forneça um nome de pacote com.function
    Fornecer um nome de função DurableFunctionsOrchestrator
  4. Escolha Select storage account na janela pop-up solicitando para configurar as informações da conta de armazenamento e siga as instruções.

Agora você deve ter as três funções básicas para um aplicativo Durable Functions geradas.

Configurar pom.xml e host.json

Adicione a seguinte dependência ao seu pom.xml:

<dependency>
  <groupId>com.microsoft</groupId>
  <artifactId>durabletask-azure-functions</artifactId>
  <version>1.0.0</version>
</dependency>

Adicione a extensions propriedade ao seu host.json:

"extensions": { "durableTask": { "hubName": "JavaTestHub" }}

Testar localmente a função

As Ferramentas de Núcleo das Funções do Azure permitem-lhe executar um projeto de funções do Azure no seu computador de programação local.

Nota

O Durable Functions for Java requer o Azure Functions Core Tools v4.0.4915 ou mais recente. Você pode ver qual versão está instalada executando o func --version comando do terminal.

  1. Se você estiver usando o Visual Studio Code, abra uma nova janela de terminal e execute os seguintes comandos para criar o projeto:

    mvn clean package
    

    Em seguida, execute a função durável:

    mvn azure-functions:run
    
  2. No painel Terminal, copie o ponto final do URL da sua função acionada por HTTP.

    Screenshot of Azure local output.

  3. Usando uma ferramenta como Postman ou cURL, envie uma solicitação HTTP POST para o ponto de extremidade URL. Deverá obter uma resposta semelhante à seguinte:

    {
        "id": "d1b33a60-333f-4d6e-9ade-17a7020562a9",
        "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9?code=ACCupah_QfGKoFXydcOHH9ffcnYPqjkddSawzRjpp1PQAzFueJ2tDw==",
        "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9/raiseEvent/{eventName}?code=ACCupah_QfGKoFXydcOHH9ffcnYPqjkddSawzRjpp1PQAzFueJ2tDw==",
        "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9?code=ACCupah_QfGKoFXydcOHH9ffcnYPqjkddSawzRjpp1PQAzFueJ2tDw==",
        "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9/terminate?reason={text}&code=ACCupah_QfGKoFXydcOHH9ffcnYPqjkddSawzRjpp1PQAzFueJ2tDw=="
    }
    

    A resposta é o resultado inicial da função HTTP informando que a orquestração durável foi iniciada com êxito. Ainda não é o resultado final da orquestração. A resposta inclui alguns URLs úteis. Por enquanto, vamos consultar o status da orquestração.

  4. Copie o valor do URL e cole-o na barra de endereço do navegador e statusQueryGetUri execute a solicitação. Como alternativa, você também pode continuar a usar Postman ou cURL para emitir a solicitação GET.

    A solicitação consultará a instância de orquestração para obter o status. Você deve obter uma eventual resposta, que nos mostra que a instância foi concluída e inclui as saídas ou resultados da função durável. Tem a seguinte aparência:

    {
        "name": "Cities",
        "instanceId": "d1b33a60-333f-4d6e-9ade-17a7020562a9",
        "runtimeStatus": "Completed",
        "input": null,
        "customStatus": "",
        "output":"TOKYO, LONDON, SEATTLE, AUSTIN",
        "createdTime": "2022-12-12T05:00:02Z",
        "lastUpdatedTime": "2022-12-12T05:00:06Z"
    }