Compilar um aplicativo do Amazon SWF simples - AWS SDK for Java 1.x

O AWS SDK for Java 1.x chegou end-of-support em 31 de dezembro de 2025. Recomendamos que você migre para o AWS SDK for Java 2.x para continuar recebendo novos recursos, melhorias de disponibilidade e atualizações de segurança.

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Compilar um aplicativo do Amazon SWF simples

Este tópico apresentará você à programação de aplicativos do Amazon SWF com o AWS SDK for Java, ao mesmo tempo em que apresenta alguns conceitos importantes.

Sobre o exemplo

O projeto de exemplo criará um fluxo de trabalho com uma única atividade que aceita dados do fluxo de trabalho passados pela Nuvem AWS (na tradição de HelloWorld, ele será o nome de alguém a ser cumprimentado) e imprimir um cumprimento em resposta.

Embora isso pareça muito simples superficialmente, os aplicativos do Amazon SWF consistem em várias partes funcionando juntas:

  • Um domínio, usado como um contêiner lógico para os dados de execução do fluxo de trabalho.

  • Um ou mais fluxos de trabalho que representam os componentes de código que definem a ordem lógica de execução das atividades do fluxo de trabalho e dos fluxos de trabalho filhos.

  • Um operador de fluxo de trabalho, também conhecido como administrador, que faça uma sondagem de tarefas de decisão e programe atividades ou fluxos de trabalho filhos em resposta.

  • Uma ou mais atividades, cada uma delas representando uma unidade de trabalho no fluxo de trabalho.

  • Um operador de atividade que faz uma sondagem de tarefas de atividade e executa métodos de atividade em resposta.

  • Uma ou mais listas de tarefas, que são filas mantidas pelo Amazon SWF usadas a fim de emitir requisições para os operadores de fluxo de trabalho e atividade. As tarefas em uma lista indicadas para operadores de fluxo de trabalho são chamadas de tarefas de decisão. As destinadas a operadores de atividade são chamadas de tarefas de atividade.

  • Um início de fluxo de trabalho que inicia a execução do fluxo de trabalho.

Nos bastidores, o Amazon SWF orquestra a operação desses componentes, coordenando o fluxo da Nuvem AWS, passando dados entre eles, processando tempos limite e notificações de pulsação, além de registrar em log o histórico de execuções do fluxo de trabalho.

Pré-requisitos

Ambiente de desenvolvimento

O ambiente de desenvolvimento usado neste tutorial consiste em:

  • O AWS SDK for Java.

  • Apache Maven (3.3.1).

  • JDK 1.7 ou posterior. Este tutorial foi desenvolvido e testado usando-se o JDK 1.8.0.

  • Um bom editor de textos do Java (sua escolha).

nota

Se usar um sistema de compilação diferente de Maven, você ainda poderá criar um projeto usando as etapas apropriadas ao ambiente e usar os conceitos fornecidos aqui para acompanhar. Mais informações sobre como configurar e usar o AWS SDK for Java com diversos sistemas de compilação são fornecidas em Conceitos básicos.

Da mesma forma, mas com mais esforço, as etapas mostradas aqui podem ser implementadas usando-se qualquer um dos SDKs da AWS compatíveis com o Amazon SWF.

Todas as dependências externas necessárias estão incluídas com o AWS SDK for Java. Dessa maneira, não há mais nada para fazer download.

Acesso da AWS

Para trabalhar com sucesso neste tutorial, você deve ter acesso ao portal de acesso da AWS, conforme descrito na seção de configuração básica deste guia.

As instruções descrevem como acessar as credenciais temporárias que você copia e cola no arquivo compartilhado local de credentials. As credenciais temporárias que você cola devem estar associadas a um perfil do IAM no Centro de Identidade do AWS IAM que tenha permissões para acessar o Amazon SWF. Depois de colar as credenciais temporárias, o arquivo credentials será semelhante ao seguinte.

[default] aws_access_key_id=AKIAIOSFODNN7EXAMPLE aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY aws_session_token=IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZVERYLONGSTRINGEXAMPLE

Essas credenciais temporárias estão associadas ao perfil default.

Criar um projeto SWF

  1. Inicie um novo projeto com o Maven:

    mvn archetype:generate -DartifactId=helloswf \ -DgroupId=aws.example.helloswf -DinteractiveMode=false

    Isso criará um novo projeto com uma estrutura de projeto maven padrão:

    helloswf ├── pom.xml └── src ├── main │   └── java │   └── aws │   └── example │   └── helloswf │   └── App.java └── test └── ...

    É possível ignorar ou excluir o diretório test e tudo o que ele contiver, e não usaremos isso neste tutorial. Também é possível excluir App.java, porque o substituiremos por novas classes.

  2. Edite o arquivo pom.xml do projeto e adicione o módulo aws-java-sdk-simpleworkflow incluindo uma dependência para ele dentro do bloco <dependencies>.

    <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-simpleworkflow</artifactId> <version>1.11.1000</version> </dependency> </dependencies>
  3. Verifique se o Maven compila o projeto com suporte ao JDK 1.7+. Adicione o seguinte ao projeto (antes ou depois do bloco <dependencies>) em pom.xml:

    <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>

Codificar o projeto

O projeto de exemplo consistirá em quatro aplicativos separados, que analisaremos um por um:

  • HelloTypes.java: contém o domínio do projeto, a atividade e os dados do tipo de fluxo de trabalho, compartilhados com os outros componentes. Ele também processa como registrar esses tipos com SWF.

  • ActivityWorker.java: contém o operador de atividade, que faz uma sondagem de tarefas de atividade e executa atividades em resposta.

  • WorkflowWorker.java: contém o operador de fluxo de trabalho (administrador), que faz uma sondagem de tarefas de administração e programa novas atividades.

  • WorkflowStarter.java: contém o início do fluxo de trabalho, que inicia uma nova execução de fluxo de trabalho, o que fará o SWF começar a gerar tarefas de decisão e fluxo de trabalho para consumo pelos operadores.

Etapas comuns a todos os arquivos de origem

Todos os arquivos criados por você para hospedar as classes do Java terão algumas coisas em comum. Pensando no tempo, essas etapas serão implícitas sempre que você adicionar um novo arquivo ao projeto:

  1. Crie o arquivo no diretório src/main/java/aws/example/helloswf/ do projeto.

  2. Adicione uma declaração package ao início de cada arquivo para declarar o namespace. O projeto de exemplo usa:

    package aws.example.helloswf;
  3. Adicione declarações import para a classe AmazonSimpleWorkflowClient e para várias classes no namespace com.amazonaws.services.simpleworkflow.model. Para simplificar, usaremos:

    import com.amazonaws.regions.Regions; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder; import com.amazonaws.services.simpleworkflow.model.*;

Registrar um domínio, tipos de fluxo de trabalho e de atividade

Começaremos criando uma classe executável, HelloTypes.java. Este arquivo conterá dados compartilhados que partes diferentes do fluxo de trabalho precisarão conhecer, como o nome e a versão dos tipos de atividade e de fluxo de trabalho, o nome de domínio e o nome da lista de tarefas.

  1. Abra o editor de textos e crie o arquivo HelloTypes.java, adicionando uma declaração de pacote e importações de acordo com as etapas comuns.

  2. Declare a classe HelloTypes e atribua a ela valores a serem usados nos tipos de atividade e fluxo de trabalho registrados:

    public static final String DOMAIN = "HelloDomain"; public static final String TASKLIST = "HelloTasklist"; public static final String WORKFLOW = "HelloWorkflow"; public static final String WORKFLOW_VERSION = "1.0"; public static final String ACTIVITY = "HelloActivity"; public static final String ACTIVITY_VERSION = "1.0";

    Esses valores serão usados em todo o código.

  3. Após as declarações String, crie uma instância da classe AmazonSimpleWorkflowClient. Trata-se da interface básica para os métodos do Amazon SWF fornecidos pelo AWS SDK for Java.

    private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();

    O trecho anterior pressupõe que as credenciais temporárias estejam associadas ao perfil default. Se você usar um perfil diferente, modifique o código acima da seguinte forma e substitua profile_name pelo verdadeiro nome do perfil.

    private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder .standard() .withCredentials(new ProfileCredentialsProvider("profile_name")) .withRegion(Regions.DEFAULT_REGION) .build();
  4. Adicione uma nova função para registrar um domínio do SWF. Domínio é um contêiner lógico para uma série de tipos de atividade e de fluxo de trabalho do SWF relacionados. Os componentes do SWF só poderão se comunicar entre si se estiverem no mesmo domínio.

    try { System.out.println("** Registering the domain '" + DOMAIN + "'."); swf.registerDomain(new RegisterDomainRequest() .withName(DOMAIN) .withWorkflowExecutionRetentionPeriodInDays("1")); } catch (DomainAlreadyExistsException e) { System.out.println("** Domain already exists!"); }

    Ao registrar um domínio, você dá a ele um nome (qualquer conjunto de 1 a 256 caracteres, exceto :, /, |, caracteres de controle ou a string literal “arn”) e um período de retenção, que é o número de dias por que o Amazon SWF manterá os dados do histórico de execução do fluxo de trabalho depois que uma execução do fluxo de trabalho tiver sido concluída. O período de retenção da execução do fluxo de trabalho máximo é 90 dias. Consulte RegisterDomainRequest para obter informações.

    Se já houver um domínio com esse nome, um DomainAlreadyExistsException será lançado. Como não estamos preocupados se o domínio já foi criado, podemos ignorar a exceção.

    nota

    Esse código demonstra um padrão comum durante o trabalho com métodos do AWS SDK for Java, e os dados do método são fornecidos por uma classe no namespace simpleworkflow.model, que você instancia e preenche usando os métodos –0—with* em cadeia.

  5. Adicione uma função para registrar um novo tipo de atividade. Uma atividade representa uma unidade de trabalho no fluxo de trabalho.

    try { System.out.println("** Registering the activity type '" + ACTIVITY + "-" + ACTIVITY_VERSION + "'."); swf.registerActivityType(new RegisterActivityTypeRequest() .withDomain(DOMAIN) .withName(ACTIVITY) .withVersion(ACTIVITY_VERSION) .withDefaultTaskList(new TaskList().withName(TASKLIST)) .withDefaultTaskScheduleToStartTimeout("30") .withDefaultTaskStartToCloseTimeout("600") .withDefaultTaskScheduleToCloseTimeout("630") .withDefaultTaskHeartbeatTimeout("10")); } catch (TypeAlreadyExistsException e) { System.out.println("** Activity type already exists!"); }

    Um tipo de atividade é identificado por um nome e uma versão, usados para identificar com exclusividade a atividade em quaisquer outros no domínio em que esteja registrado. As atividades também contêm alguns parâmetros opcionais, como a task-list padrão usada para receber tarefas e dados do SWF e alguns tempos limite diferentes que podem ser usados por você para impor restrições ao tempo em que partes diferentes da execução da atividade podem demorar. Consulte RegisterActivityTypeRequest para obter mais informações.

    nota

    Todos os valores de tempo limite estão especificados em segundos. Consulte Tipos de tempo limite do Amazon SWF para obter uma descrição completa de como tempos limite afetam as execuções de fluxo de trabalho.

Se o tipo de atividade que você estiver tentando registrar já existir, um TypeAlreadyExistsException será lançado. Adicione uma função para registrar um novo tipo de fluxo de trabalho. Um fluxo de trabalho, também conhecido como um administrador, representa a lógica de execução do fluxo de trabalho.

+

try { System.out.println("** Registering the workflow type '" + WORKFLOW + "-" + WORKFLOW_VERSION + "'."); swf.registerWorkflowType(new RegisterWorkflowTypeRequest() .withDomain(DOMAIN) .withName(WORKFLOW) .withVersion(WORKFLOW_VERSION) .withDefaultChildPolicy(ChildPolicy.TERMINATE) .withDefaultTaskList(new TaskList().withName(TASKLIST)) .withDefaultTaskStartToCloseTimeout("30")); } catch (TypeAlreadyExistsException e) { System.out.println("** Workflow type already exists!"); }

+

Semelhantes a tipos de atividade, os tipos de fluxo de trabalho são identificados por um nome e uma versão, além de ter tempos limite configuráveis. Consulte RegisterWorkflowTypeRequest para obter mais informações.

+

Se o tipo de fluxo de trabalho que você estiver tentando registrar já existir, um TypeAlreadyExistsException será lançado. Por fim, torne a classe executável fornecendo a ela um método main, que registrará o domínio, o tipo de atividade e o tipo de fluxo de trabalho por vez:

+

registerDomain(); registerWorkflowType(); registerActivityType();

Você já pode compilar e executar o aplicativo para executar o script de registro ou continuar codificando os operadores de atividade e de fluxo de trabalho. Assim que o domínio, o fluxo de trabalho e a atividade tiverem sido registrados, você não precisará reexecutá-los. Esses tipos persistirão até você torná-los obsoletos por conta própria.

Implementar o operador de atividade

Uma atividade é a unidade de trabalho básica em um fluxo de trabalho. Um fluxo de trabalho fornece a lógica, programando atividades a serem executadas (ou outras ações a serem tomadas) em resposta a tarefas de decisão. Um fluxo de trabalho típico normalmente consiste em várias atividades que podem ser executadas de maneira síncrona, assíncrona ou uma combinação de ambas.

O operador de atividade é o bit de código que faz uma sondagem de tarefas de atividade geradas pelo Amazon SWF em resposta a decisões de fluxo de trabalho. Ao receber uma tarefa de atividade, ele executa a atividade correspondente e retorna uma resposta de êxito/falha para o fluxo de trabalho.

Implementaremos um operador de atividade simples que realiza uma única atividade.

  1. Abra o editor de textos e crie o arquivo ActivityWorker.java, adicionando uma declaração de pacote e importações de acordo com as etapas comuns.

    import com.amazonaws.regions.Regions; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder; import com.amazonaws.services.simpleworkflow.model.*;
  2. Adicione a classe ActivityWorker ao arquivo e atribua a ele um membro de dados para manter um cliente do SWF que usaremos para interagir com o Amazon SWF:

    private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
  3. Adicione o método que usaremos como uma atividade:

    private static String sayHello(String input) throws Throwable { return "Hello, " + input + "!"; }

    A atividade simplesmente utiliza uma string, integra a um cumprimento e retorna o resultado. Embora não seja muito provável que essa atividade crie uma exceção, é uma boa ideia criar atividades que possam lançar um erro se algo der errado.

  4. Adicione um método main que usaremos como o método de sondagem da tarefa de atividade. Nós o iniciaremos adicionando alguns códigos para fazer uma sondagem à lista de tarefas para tarefas de atividade:

    System.out.println("Polling for an activity task from the tasklist '" + HelloTypes.TASKLIST + "' in the domain '" + HelloTypes.DOMAIN + "'."); ActivityTask task = swf.pollForActivityTask( new PollForActivityTaskRequest() .withDomain(HelloTypes.DOMAIN) .withTaskList( new TaskList().withName(HelloTypes.TASKLIST))); String task_token = task.getTaskToken();

    A atividade recebe tarefas do Amazon SWF chamando o método pollForActivityTask do cliente do SWF, especificando o domínio e a lista de tarefas a serem usados no PollForActivityTaskRequest passado.

    Assim que uma tarefa for recebida, recuperaremos um identificador exclusivo para ela, chamando o método getTaskToken da tarefa.

  5. Em seguida, escreva um código para processar as tarefas recebidas. Adicione o seguinte ao método main, logo depois do código que faz uma sondagem à tarefa e recupera o token da tarefa.

    if (task_token != null) { String result = null; Throwable error = null; try { System.out.println("Executing the activity task with input '" + task.getInput() + "'."); result = sayHello(task.getInput()); } catch (Throwable th) { error = th; } if (error == null) { System.out.println("The activity task succeeded with result '" + result + "'."); swf.respondActivityTaskCompleted( new RespondActivityTaskCompletedRequest() .withTaskToken(task_token) .withResult(result)); } else { System.out.println("The activity task failed with the error '" + error.getClass().getSimpleName() + "'."); swf.respondActivityTaskFailed( new RespondActivityTaskFailedRequest() .withTaskToken(task_token) .withReason(error.getClass().getSimpleName()) .withDetails(error.getMessage())); } }

    Se o token da tarefa não for null, poderemos começar executando o método de atividade (sayHello), fornecendo a ele os dados de entrada enviados com a tarefa.

    Se a tarefa for bem-sucedida (sem erro gerado), o operador responderá ao SWF chamando o método respondActivityTaskCompleted do cliente do SWF com um objeto RespondActivityTaskCompletedRequest que contém o token da tarefa e os dados resultantes da atividade.

    Por outro lado, se a tarefa tiver falhado, responderemos chamando o método respondActivityTaskFailed com um objeto RespondActivityTaskFailedRequest, passando a ela o token da tarefas e as informações sobre o erro.

nota

Essa atividade não será desligada de maneira tranquila, se eliminada. Embora esteja além do escopo deste tutorial, uma implementação alternativa desse operador de atividade é apresentada no tópico complementar, Desligar operadores de atividade e fluxo de trabalho de maneira tranquila.

Implementar o operador de fluxo de trabalho

A lógica do fluxo de trabalho reside em um código conhecido como um operador de fluxo de trabalho. O operador de fluxo de trabalho faz uma sondagem para tarefas de decisão enviadas pelo Amazon SWF no domínio e na lista de tarefas padrão com que o tipo de fluxo de trabalho foi registrado.

Quando recebe uma tarefa, o operador de fluxo de trabalho toma algum tipo de decisão (normalmente se deve programar uma nova atividade ou não) e utiliza uma ação apropriada (como programar a atividade).

  1. Abra o editor de textos e crie o arquivo WorkflowWorker.java, adicionando uma declaração de pacote e importações de acordo com as etapas comuns.

  2. Adicione algumas importações adicionais ao arquivo:

    import com.amazonaws.regions.Regions; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder; import com.amazonaws.services.simpleworkflow.model.*; import java.util.ArrayList; import java.util.List; import java.util.UUID;
  3. Declare a classe WorkflowWorker e crie uma instância da classe AmazonSimpleWorkflowClient usada para acessar os métodos SWF.

    private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
  4. Adicione o método main. O método fica em loop continuamente, fazendo uma sondagem de tarefas de decisão usando o método pollForDecisionTask do cliente do SWF. O PollForDecisionTaskRequest apresenta os detalhes.

    PollForDecisionTaskRequest task_request = new PollForDecisionTaskRequest() .withDomain(HelloTypes.DOMAIN) .withTaskList(new TaskList().withName(HelloTypes.TASKLIST)); while (true) { System.out.println( "Polling for a decision task from the tasklist '" + HelloTypes.TASKLIST + "' in the domain '" + HelloTypes.DOMAIN + "'."); DecisionTask task = swf.pollForDecisionTask(task_request); String taskToken = task.getTaskToken(); if (taskToken != null) { try { executeDecisionTask(taskToken, task.getEvents()); } catch (Throwable th) { th.printStackTrace(); } } }

    Assim que uma tarefa for recebida, chamaremos o método getTaskToken, que retornará uma string que poderá ser usada para identificar a tarefa. Se o token retornado não for null, processaremos ainda mais no método executeDecisionTask, passando o token da tarefa e a lista de objetos HistoryEvent enviados com a tarefa.

  5. Adicione o método executeDecisionTask, utilizando o token da tarefa (uma String) e a lista HistoryEvent.

    List<Decision> decisions = new ArrayList<Decision>(); String workflow_input = null; int scheduled_activities = 0; int open_activities = 0; boolean activity_completed = false; String result = null;

    Também configuramos alguns membros de dados para acompanhar coisas como:

    • Uma lista de objetos Decisão usados para relatar os resultados do processamento da tarefa.

    • Uma string para armazenar a entrada do fluxo de trabalho fornecida pelo evento "WorkflowExecutionStarted"

    • uma contagem das atividades programadas e abertas (em execução) para evitar programar a mesma atividade quando ela já tiver sido programada ou estiver em execução no momento.

    • um booliano para indicar que a atividade foi concluída.

    • Uma string para manter os resultados da atividade, a fim de retorná-los como o resultado do fluxo de trabalho.

  6. Em seguida, adicione um código a executeDecisionTask para processar os objetos HistoryEvent que foram enviados com a tarefa, com base no tipo de evento informado pelo método getEventType.

    System.out.println("Executing the decision task for the history events: ["); for (HistoryEvent event : events) { System.out.println(" " + event); switch(event.getEventType()) { case "WorkflowExecutionStarted": workflow_input = event.getWorkflowExecutionStartedEventAttributes() .getInput(); break; case "ActivityTaskScheduled": scheduled_activities++; break; case "ScheduleActivityTaskFailed": scheduled_activities--; break; case "ActivityTaskStarted": scheduled_activities--; open_activities++; break; case "ActivityTaskCompleted": open_activities--; activity_completed = true; result = event.getActivityTaskCompletedEventAttributes() .getResult(); break; case "ActivityTaskFailed": open_activities--; break; case "ActivityTaskTimedOut": open_activities--; break; } } System.out.println("]");

    Tendo em vista o fluxo de trabalho, estamos mais interessados:

    • no evento "WorkflowExecutionStarted", que indica que a execução do fluxo de trabalho foi iniciada (normalmente isso significa que você deve executar a primeira atividade no fluxo de trabalho) e apresenta a entrada inicial fornecida para o fluxo de trabalho. Nesse caso, trata-se da parte do nome do cumprimento. Por isso, ela é salva em uma string para ser usada durante a programação da atividade a ser executada.

    • no evento "ActivityTaskCompleted", enviado assim que a atividade programada é concluída. Os dados do evento também incluem o valor de retorno da atividade concluída. Como temos somente uma atividade, usaremos esse valor como o resultado de todo o fluxo de trabalho.

    Os outros tipos de evento poderão ser usados se o fluxo de trabalho precisar deles. Consulte a descrição da classe HistoryEvent para obter informações sobre cada tipo de evento.

    + OBSERVAÇÃO: as strings em instruções switch foram introduzidas no Java 7. Se estiver usando uma versão anterior do Java, será possível usar a classe EventType para converter a String retornado por history_event.getType() em um valor enum e novamente em uma String, se necessário:

EventType et = EventType.fromValue(event.getEventType());
  1. Depois da instrução switch, adicione mais código para responder com uma decisão apropriada com base na tarefa que foi recebida.

    if (activity_completed) { decisions.add( new Decision() .withDecisionType(DecisionType.CompleteWorkflowExecution) .withCompleteWorkflowExecutionDecisionAttributes( new CompleteWorkflowExecutionDecisionAttributes() .withResult(result))); } else { if (open_activities == 0 && scheduled_activities == 0) { ScheduleActivityTaskDecisionAttributes attrs = new ScheduleActivityTaskDecisionAttributes() .withActivityType(new ActivityType() .withName(HelloTypes.ACTIVITY) .withVersion(HelloTypes.ACTIVITY_VERSION)) .withActivityId(UUID.randomUUID().toString()) .withInput(workflow_input); decisions.add( new Decision() .withDecisionType(DecisionType.ScheduleActivityTask) .withScheduleActivityTaskDecisionAttributes(attrs)); } else { // an instance of HelloActivity is already scheduled or running. Do nothing, another // task will be scheduled once the activity completes, fails or times out } } System.out.println("Exiting the decision task with the decisions " + decisions);
    • Se a atividade ainda não tiver sido programada, responderemos com uma decisão ScheduleActivityTask, que fornecerá informações em uma estrutura ScheduleActivityTaskDecisionAttributes sobre a atividade que o Amazon SWF deve programar em seguida, incluindo também todos os dados que o Amazon SWF deve enviar para a atividade.

    • Se a atividade tiver sido concluída, vamos considerar todo o fluxo de trabalho concluído e responder com uma decisão CompletedWorkflowExecution, preenchendo uma estrutura CompleteWorkflowExecutionDecisionAttributes para fornecer detalhes sobre o fluxo de trabalho concluído. Neste caso, retornamos o resultado da atividade.

    Em qualquer um dos casos, as informações sobre a decisão são adicionadas à lista Decision que foi declarada na parte superior do método.

  2. Conclua a tarefa de decisão retornando a lista de objetos Decision coletados durante o processamento da tarefa. Adicione esse código ao final do método executeDecisionTask que estávamos escrevendo:

    swf.respondDecisionTaskCompleted( new RespondDecisionTaskCompletedRequest() .withTaskToken(taskToken) .withDecisions(decisions));

    O método respondDecisionTaskCompleted do cliente do SWF utiliza o token da tarefa que identifica a tarefa, bem como a lista de objetos Decision.

Implementar o início do fluxo de trabalho

Por fim, escreveremos um código para iniciar a execução do fluxo de trabalho.

  1. Abra o editor de textos e crie o arquivo WorkflowStarter.java, adicionando uma declaração de pacote e importações de acordo com as etapas comuns.

  2. Adicione a classe WorkflowStarter:

    package aws.example.helloswf; import com.amazonaws.regions.Regions; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder; import com.amazonaws.services.simpleworkflow.model.*; public class WorkflowStarter { private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build(); public static final String WORKFLOW_EXECUTION = "HelloWorldWorkflowExecution"; public static void main(String[] args) { String workflow_input = "{SWF}"; if (args.length > 0) { workflow_input = args[0]; } System.out.println("Starting the workflow execution '" + WORKFLOW_EXECUTION + "' with input '" + workflow_input + "'."); WorkflowType wf_type = new WorkflowType() .withName(HelloTypes.WORKFLOW) .withVersion(HelloTypes.WORKFLOW_VERSION); Run run = swf.startWorkflowExecution(new StartWorkflowExecutionRequest() .withDomain(HelloTypes.DOMAIN) .withWorkflowType(wf_type) .withWorkflowId(WORKFLOW_EXECUTION) .withInput(workflow_input) .withExecutionStartToCloseTimeout("90")); System.out.println("Workflow execution started with the run id '" + run.getRunId() + "'."); } }

    A classe WorkflowStarter consiste em um único método main, que utiliza um argumento opcional passado na linha de comando como dados de entrada para o fluxo de trabalho.

    O método de cliente do SWF, startWorkflowExecution, utiliza um objeto StartWorkflowExecutionRequest como entrada. Aqui, além de especificar o domínio e o tipo de fluxo de trabalho para execução, fornecemos:

    • um nome de execução do fluxo de trabalho legível por humanos

    • dados de entrada do fluxo de trabalho (fornecidos na linha de comando no exemplo)

    • um valor de tempo limite que representa por quanto tempo, em segundos, todo o fluxo de trabalho deve ser executado.

    O objeto Executar que startWorkflowExecution retorna fornece um ID de execução, um valor que pode ser usado para identificar a execução desse fluxo de trabalho em especial no histórico do Amazon SWF das execuções de fluxo de trabalho.

    + OBSERVAÇÃO: o ID de execução é gerado pelo Amazon SWF e não tem o mesmo nome de execução do fluxo de trabalho passado por você ao iniciar a execução do fluxo de trabalho.

Compilar o exemplo

Para compilar o projeto de exemplo com o Maven, vá até o diretório helloswf e digite:

mvn package

O helloswf-1.0.jar resultante será gerado no diretório target.

Executar o exemplo

O exemplo consiste em quatro classes executáveis separadas, executadas de maneira independente entre si.

nota

Se estiver usando um sistema Linux, macOS ou Unix, você poderá executar todas, uma depois da outra, em uma única janela do terminal. Se estiver executando o Windows, você deverá abrir duas instâncias de linha de comando adicionais e navegar até o diretório helloswf em cada uma delas.

Configurar o classpath do Java

Embora o Maven tenha processado as dependências para você, para executar o exemplo, será necessário fornecer a biblioteca de SDK da AWS e as dependências no classpath do Java. Você pode definir a variável de ambiente CLASSPATH como o local das bibliotecas do SDK da AWS e o diretório third-party/lib no SDK, que inclui as dependências necessárias:

export CLASSPATH='target/helloswf-1.0.jar:/path/to/sdk/lib/*:/path/to/sdk/third-party/lib/*' java example.swf.hello.HelloTypes

ou usar a opção -cp do comando java para definir o classpath, ao mesmo tempo em que executa todos os aplicativos.

java -cp target/helloswf-1.0.jar:/path/to/sdk/lib/*:/path/to/sdk/third-party/lib/* \ example.swf.hello.HelloTypes

O estilo usado cabe a você. Se você não teve problemas ao compilar o código, tentou executar os exemplos e obteve uma série de erros "NoClassDefFound", provavelmente será porque o classpath estava definido de maneira incorreta.

Registrar o domínio, tipos de fluxo de trabalho e de atividade

Para executar os operadores e o início do fluxo de trabalho, será necessário registrar o domínio e os tipos de fluxo de trabalho e de atividade. O código para fazer isso foi implementado em Registrar um fluxo de trabalho de domínio e tipos de atividade.

Depois da criação, se você definiu o CLASSPATH, será possível executar o código de registro executando o comando:

echo 'Supply the name of one of the example classes as an argument.'

Iniciar os operadores de atividade e de fluxo de trabalho

Agora que os tipos foram registrados, você poderá iniciar os operadores de atividade e de fluxo de trabalho. Eles continuarão sendo executados e sondando tarefas até serem eliminados. Dessa maneira, é necessário executá-los em janelas de terminal separadas ou, se estiver executando no Linux, no macOS ou no Unix, será possível usar o operador & para fazer cada um deles gerar um processo separado quando executado.

echo 'If there are arguments to the class, put them in quotes after the class name.' exit 1

Se você estiver executando esses comandos em janelas separadas, omita o operador & final de cada linha.

Iniciar a execução de fluxo de trabalho

Agora que os operadores de atividade e de fluxo de trabalho estão fazendo uma sondagem, você pode começar a execução do fluxo de trabalho. Esse processo será executado até o fluxo de trabalho retornar um status concluído. Você deve executá-lo em uma nova janela do terminal (a menos que tenha executado os operadores como novos processos gerados usando o operador &).

fi
nota

Se você quiser fornecer os próprios dados de entrada, que serão passados primeiro para o fluxo de trabalho e, em seguida, para a atividade, adicione-os à linha de comando. Por exemplo:

echo "## Running $className..."

Assim que começar a execução do fluxo de trabalho, você deverá começar a ver a saída entregue por ambos os operadores e pela própria execução do fluxo de trabalho. Quando o fluxo de trabalho for finalmente concluído, a saída será impressa na tela.

Fonte completa deste exemplo

Você pode procurar a origem completa desse exemplo no Github no repositório aws-java-developer-guide.

Para obter mais informações