Creación de una Amazon SWF aplicación sencilla - AWS SDK para Java 1.x

La AWS SDK para Java versión 1.x entró en modo de mantenimiento el 31 de julio de 2024 y estará disponible el 31 de end-of-supportdiciembre de 2025. Le recomendamos que migre al para AWS SDK for Java 2.xseguir recibiendo nuevas funciones, mejoras de disponibilidad y actualizaciones de seguridad.

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Creación de una Amazon SWF aplicación sencilla

En este tema se introducirá en la programación de Amazon SWFaplicaciones con el AWS SDK para Java, a la vez que se presentarán algunos conceptos importantes a lo largo del proceso.

Acerca del ejemplo

El proyecto de ejemplo creará un flujo de trabajo con una sola actividad que acepte los datos del flujo de trabajo transmitidos a través de la AWS nube (según la tradición HelloWorld, será el nombre de alguien a quien saludar) y, a continuación, imprimirá un saludo como respuesta.

Si bien esto parece muy simple a primera vista, Amazon SWF las aplicaciones constan de una serie de partes que trabajan juntas:

  • Un dominio, utilizado como un contenedor lógico para los datos de ejecución del flujo de trabajo.

  • Uno o varios flujos de trabajo que representan los componentes de código que definen el orden lógico de ejecución de las actividades del flujo de trabajo y los flujos de trabajo secundarios.

  • Un proceso de trabajo de flujo de trabajo, también conocido como decisor, que busca tareas de decisión y actividades de programación o flujos de trabajo secundarios como respuesta.

  • Una o varias actividades, cada una de las cuales representa una unidad de trabajo del flujo de trabajo.

  • Un proceso de trabajo de actividad que busca tareas de actividad y ejecuta métodos de actividad como respuesta.

  • Una o más listas de tareas, que son colas mantenidas que se Amazon SWF utilizan para emitir solicitudes a los trabajadores del flujo de trabajo y de la actividad. Las tareas de una lista de tareas dirigidas a los procesos de trabajo de flujo de trabajo se denominan tareas de decisión. Las dirigidas a los procesos de trabajo de actividad se denominan tareas de actividad.

  • Un iniciador del flujo de trabajo que inicia la ejecución del flujo de trabajo.

Entre bastidores, Amazon SWF organiza el funcionamiento de estos componentes, coordinando su flujo desde la AWS nube, pasando datos entre ellos, gestionando los tiempos de espera y las notificaciones de latidos, y registrando el historial de ejecución del flujo de trabajo.

Requisitos previos

Entorno de desarrollo

El entorno de desarrollo que se utiliza en este tutorial se compone de:

  • La AWS SDK para Java.

  • Apache Maven (3.3.1).

  • JDK 1.7 o posterior. Este tutorial se ha desarrollado y probado con JDK 1.8.0.

  • Un buen editor de texto de Java (el que prefiera).

nota

Si utiliza un sistema de compilación distinto de Maven, puede crear igualmente un proyecto realizando los pasos correspondientes de su entorno y usar los conceptos que se proporcionan aquí durante el proceso. Encontrará más información sobre la configuración y el uso AWS SDK para Java de los distintos sistemas de compilación en Cómo empezar.

Del mismo modo, pero con más esfuerzo, los pasos que se muestran aquí se pueden implementar utilizando cualquiera de los compatibles AWS SDKs con Amazon SWF.

Todas las dependencias externas necesarias están incluidas en el AWS SDK para Java, por lo que no hay nada adicional que descargar.

AWS Acceso

Para completar correctamente este tutorial, debe tener acceso al portal de AWS acceso tal como se describe en la sección de configuración básica de esta guía.

Las instrucciones describen cómo acceder a las credenciales temporales que se copian y pegan en el archivo de credentials compartido local. Las credenciales temporales que pegue deben estar asociadas a un rol de IAM en AWS IAM Identity Center que tenga permisos para acceder a Amazon SWF. Tras pegar las credenciales temporales, el archivo de credentials debería tener un aspecto similar al siguiente.

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

Estas credenciales temporales están asociadas al perfil default.

Creación de un proyecto de SWF

  1. Inicie un nuevo proyecto con Maven:

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

    Se creará un nuevo proyecto con una estructura de proyecto de Maven estándar:

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

    Puede omitir o eliminar el directorio test y todo su contenido; no lo usaremos en este tutorial. También puede eliminar App.java, ya que lo reemplazaremos por nuevas clases.

  2. Edite el pom.xml archivo del proyecto y añada el aws-java-sdk-simpleworkflowmódulo añadiendo una dependencia para él dentro del <dependencies> bloque.

    <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-simpleworkflow</artifactId> <version>1.11.1000</version> </dependency> </dependencies>
  3. Asegúrese de que Maven compila su proyecto de manera que sea compatible con JDK 1.7+. Añada lo siguiente a su proyecto (delante o detrás del bloque <dependencies>) en 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>

Codificación del proyecto

El proyecto de ejemplo consta de cuatro aplicaciones distintas, que examinaremos de una en una:

  • HelloTypes.java: contiene los datos del dominio, la actividad y el tipo de flujo de trabajo del proyecto, que se comparten con los demás componentes. También se encarga de registrar estos tipos con SWF.

  • ActivityWorker.java: contiene el elemento de trabajo de la actividad, que sondea las tareas de actividad y, en respuesta, ejecuta las actividades.

  • WorkflowWorker.java: contiene el trabajador del flujo de trabajo (decisor), que sondea las tareas de decisión y programa nuevas actividades.

  • WorkflowStarter.java: contiene el iniciador del flujo de trabajo, que inicia una nueva ejecución del flujo de trabajo, lo que hará que SWF comience a generar tareas de flujo de trabajo y decisiones para que las consuman sus trabajadores.

Pasos comunes para todos los archivos de código fuente

Todos los archivos que crea para alojar sus clases Java tendrán algunas cosas en común. Para ahorrar tiempo, estos pasos estarán implícitos cada vez que añada un nuevo archivo al proyecto:

  1. Cree el archivo en el directorio src/main/java/aws/example/helloswf/ del proyecto.

  2. Añada una declaración package al principio de cada archivo para declarar su espacio de nombres. El proyecto de ejemplo usa:

    package aws.example.helloswf;
  3. Añada import declaraciones para la AmazonSimpleWorkflowClientclase y para varias clases en el espacio de nombres. com.amazonaws.services.simpleworkflow.model Para simplificar las cosas, vamos a utilizar:

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

Registro de un dominio y de tipos de flujo de trabajo y actividad

Comenzaremos creando una nueva clase ejecutable, HelloTypes.java. Este archivo contendrá datos compartidos que necesitarán conocer las distintas partes de su flujo de trabajo, como el nombre y la versión de sus tipos de actividad y flujo de trabajo, el nombre de dominio y el nombre de la lista de tareas.

  1. Abra su editor de texto y cree el archivo HelloTypes.java, añadiendo una declaración del paquete y funciones import de acuerdo con los pasos comunes.

  2. Declare la clase HelloTypes y proporcione los valores que se van a usar para los tipos de actividad y flujo de trabajo 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";

    Estos valores se utilizarán en todo el código.

  3. Tras las declaraciones de cadena, crea una instancia de la AmazonSimpleWorkflowClientclase. Esta es la interfaz básica de los Amazon SWF métodos proporcionados por AWS SDK para Java.

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

    En el fragmento anterior se presupone que las credenciales temporales están asociadas al perfil default. Si utiliza un perfil diferente, modifique el código anterior de la siguiente manera y profile_name sustitúyalo por el nombre del perfil real.

    private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder .standard() .withCredentials(new ProfileCredentialsProvider("profile_name")) .withRegion(Regions.DEFAULT_REGION) .build();
  4. Añada una nueva función para registrar un dominio de SWF. Un dominio es un contenedor lógico para una serie de tipos de actividad y flujo de trabajo de SWF relacionados. Los componentes de SWF solo pueden comunicarse entre sí si se encuentran en el mismo dominio.

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

    Al registrar un dominio, se le proporciona un nombre (cualquier conjunto de 1 a 256 caracteres excepto:,,, /|, los caracteres de control o la cadena literal «arn») y un período de retención, que es el número de días que se Amazon SWF conservarán los datos del historial de ejecución del flujo de trabajo una vez finalizada la ejecución del flujo de trabajo. El periodo máximo de retención de ejecución del flujo de trabajo es de 90 días. Para obtener más información, consulta RegisterDomainRequest.

    Si ya existe un dominio con ese nombre, DomainAlreadyExistsExceptionse genera un. Como no nos interesa si se ha creado o no se ha creado el dominio, podemos omitir esta excepción.

    nota

    Este código muestra un patrón común cuando se trabaja con AWS SDK para Java métodos: los datos del método los proporciona una clase del espacio de simpleworkflow.model nombres, que se instancian y rellenan mediante los métodos encadenables. –0—with*

  5. Añada una función para registrar un nuevo tipo de actividad. Una actividad representa una unidad de trabajo de su flujo de trabajo.

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

    Un tipo de actividad se identifica mediante un nombre y una versión, que se utilizan para identificar de forma inequívoca la actividad de otras actividades que se han registrado en el dominio. Las actividades también contienen una serie de parámetros opcionales, como la lista de tareas predeterminadas para recibir las tareas y los datos de SWF, y una serie de tiempos de espera diferentes que puede utilizar para aplicar restricciones sobre cuánto tiempo pueden tardar las distintas partes de la ejecución de la actividad. Para obtener más información, consulta RegisterActivityTypeRequest.

    nota

    Todos los valores de tiempo de espera se especifican en segundos. Consulte Tipos de tiempo de espera de Amazon SWF para obtener una descripción completa de cómo los tiempos de espera afectan a las ejecuciones del flujo de trabajo.

Si el tipo de actividad que intentas registrar ya existe, se genera una. TypeAlreadyExistsException Añada una función para registrar un nuevo tipo de flujo de trabajo. Un flujo de trabajo, denominado también decisor, representa la lógica de la ejecución del flujo de trabajo.

+

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

+

Al igual que los tipos de actividad, los tipos de flujos de trabajo se identifican mediante un nombre y una versión, y también tienen tiempos de espera configurables. Para obtener más información, consulta RegisterWorkflowTypeRequest.

+

Si el tipo de flujo de trabajo que estás intentando registrar ya existe, TypeAlreadyExistsExceptionse genera un. Por último, cree la clase ejecutable proporcionando un método main, que registrará el dominio, el tipo de actividad y el tipo de flujo de trabajo:

+

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

Puede compilar y ejecutar la aplicación ahora para ejecutar el script de registro o continuar programando los procesos de trabajo de actividad y flujo de trabajo. Una vez que el dominio, el flujo de trabajo y la actividad se hayan registrado, no necesitará ejecutar esto de nuevo: estos tipos persisten hasta que los deja de utilizar.

Implementación del proceso de trabajo de actividad

Una actividad es la unidad básica de trabajo de su flujo de trabajo. Un flujo de trabajo proporciona la lógica, programando las actividades que se van a ejecutar (u otras acciones que se deben llevar a cabo) en respuesta a las tareas de decisión. Un flujo de trabajo típico normalmente se compone de una serie de actividades que se pueden ejecutar de forma síncrona, asíncrona o de ambas formas.

El elemento de trabajo por actividades es el fragmento de código que busca las tareas de actividad generadas por ellas Amazon SWF en respuesta a las decisiones del flujo de trabajo. Cuando recibe una tarea de actividad, ejecuta la actividad correspondiente y devuelve una respuesta de éxito/error al flujo de trabajo.

Vamos a implementar un proceso de trabajo de actividad sencillo que se encarga de una sola actividad.

  1. Abra su editor de texto y cree el archivo ActivityWorker.java, añadiendo una declaración del paquete y funciones import de acuerdo con los pasos comunes.

    import com.amazonaws.regions.Regions; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder; import com.amazonaws.services.simpleworkflow.model.*;
  2. Añada la ActivityWorker clase al archivo y asígnele un miembro de datos para que contenga un cliente SWF con Amazon SWF el que interactuaremos:

    private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
  3. Añada el método que usaremos como actividad:

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

    La actividad simplemente toma una cadena, la combina en un saludo y devuelve el resultado. Aunque no es muy probable que esta actividad produzca una excepción, es aconsejable que diseñe actividades que puedan producir un error si algo va mal.

  4. Añada un método main que utilizaremos como el método de sondeo de tareas de actividad. Empezaremos añadiendo código para buscar tareas de actividad en la lista de tareas:

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

    La actividad recibe las tareas Amazon SWF llamando al pollForActivityTask método del cliente SWF y especificando el dominio y la lista de tareas que se van a utilizar en la transferencia. PollForActivityTaskRequest

    Una vez que se recibe una tarea, recuperamos un identificador único llamando al método getTaskToken de la tarea.

  5. A continuación, escribimos código para procesar las tareas que llegan. Añada lo siguiente al método main, justo detrás del código que busca la tarea y recupera su token de tarea.

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

    Si el token de tarea no es null, podemos empezar a ejecutar el método de actividad (sayHello), facilitándole los datos de entrada que se enviaron con la tarea.

    Si la tarea se realizó correctamente (no se generó ningún error), el trabajador responde al SWF llamando al respondActivityTaskCompleted método del cliente SWF con un RespondActivityTaskCompletedRequestobjeto que contiene el token de la tarea y los datos de los resultados de la actividad.

    Por otro lado, si la tarea ha fallado, respondemos llamando al respondActivityTaskFailed método con un RespondActivityTaskFailedRequestobjeto, pasándole el token de la tarea y la información sobre el error.

nota

Esta actividad no se cerrará correctamente si se cancela. Aunque está fuera del alcance de este tutorial, una implementación alternativa de este proceso de trabajo de actividad se proporciona en el tema complementario Cerrar correctamente los procesos de trabajo de actividad y flujo de trabajo.

Implementación del proceso de trabajo del flujo de trabajo

La lógica del flujo de trabajo reside en una parte del código denominada proceso de trabajo de flujo de trabajo. El trabajador del flujo de trabajo sondea las tareas de decisión que se envían Amazon SWF en el dominio y en la lista de tareas predeterminada en la que se registró el tipo de flujo de trabajo.

Cuando el proceso de trabajo de flujo de trabajo recibe una tarea, toma algún tipo de decisión (normalmente si se va a programar o no una nueva actividad) y realiza la actividad correspondiente (como programar la actividad).

  1. Abra su editor de texto y cree el archivo WorkflowWorker.java, añadiendo una declaración del paquete y funciones import de acuerdo con los pasos comunes.

  2. Añada algunas funciones import adicionales al archivo:

    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 la WorkflowWorker clase y cree una instancia de la AmazonSimpleWorkflowClientclase utilizada para acceder a los métodos SWF.

    private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
  4. Añada el método main. Este método se ejecuta en bucle continuamente en busca de tareas de decisión usando el método pollForDecisionTask del cliente de SWF. PollForDecisionTaskRequestProporciona los detalles.

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

    Una vez que se recibe una tarea, llamamos a su método getTaskToken, que devuelve una cadena que se puede utilizar para identificar la tarea. Si el token devuelto no lo esnull, lo procesamos más adelante en el executeDecisionTask método y le pasamos el token de la tarea y la lista de HistoryEventobjetos enviados con la tarea.

  5. Añada el método executeDecisionTask, tomando el token de tarea (String) y la 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;

    También configuramos algunos miembros de datos para realizar un seguimiento de cosas como:

    • Una lista de objetos Decision usados para registrar los resultados de procesar la tarea

    • Una cadena para contener la entrada del flujo de trabajo proporcionada por el evento WorkflowExecutionStarted «»

    • Un recuento de las actividades programadas y abiertas (en ejecución) para evitar programar la misma actividad cuando ya se ha programado o se está ejecutando en este momento

    • Un valor booleano para indicar que la actividad se ha completado

    • Una cadena para almacenar los resultados de la actividad, que se devolverán como el resultado del flujo de trabajo

  6. A continuación, añada código a executeDecisionTask para procesar los objetos HistoryEvent que se han enviado a la tarea, en función del tipo de evento notificado por el 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("]");

    A efectos de nuestro flujo de trabajo, lo que más nos interesa es:

    • el evento WorkflowExecutionStarted «», que indica que se ha iniciado la ejecución del flujo de trabajo (normalmente significa que debe ejecutar la primera actividad del flujo de trabajo) y que proporciona la entrada inicial proporcionada al flujo de trabajo. En este caso, es la parte del nombre del saludo, por lo que se guarda como una cadena para usarla al programar la actividad que se debe ejecutar.

    • el evento ActivityTaskCompleted «», que se envía una vez que se completa la actividad programada. Los datos del evento también incluyen el valor devuelto de la actividad completada. Como solo tenemos una actividad, usaremos el valor como el resultado de todo el flujo de trabajo.

    Los demás tipos de eventos se pueden utilizar si el flujo de trabajo así lo requiere. Consulte la descripción HistoryEventde la clase para obtener información sobre cada tipo de evento.

    + NOTA: las cadenas de switch se introdujeron en Java 7. Si utilizas una versión anterior de Java, puedes utilizar la EventTypeclase para convertir lo String devuelto por history_event.getType() en un valor de enumeración y, String si es necesario, volver a convertirlo en un valor:

EventType et = EventType.fromValue(event.getEventType());
  1. Detrás de la instrucción switch, añada más código para responder con una decisión adecuada en función de la tarea que se ha recibido.

    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);
    • Si la actividad aún no se ha programado, respondemos con una ScheduleActivityTask decisión, que proporciona información en una ScheduleActivityTaskDecisionAttributesestructura sobre la actividad que Amazon SWF debe programarse a continuación, además de cualquier dato que Amazon SWF deba enviarse a la actividad.

    • Si la actividad se ha completado, consideramos que se ha completado todo el flujo de trabajo y respondemos con una CompletedWorkflowExecution decisión, rellenando una CompleteWorkflowExecutionDecisionAttributesestructura para proporcionar detalles sobre el flujo de trabajo completado. En este caso, devolvemos el resultado de la actividad.

    En cualquier caso, la información de la decisión se añade a la lista Decision que se declaró encima del método.

  2. Complete la tarea de decisión devolviendo la lista de objetos Decision recopilados al procesar la tarea. Añada este código al final del método executeDecisionTask que hemos escrito:

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

    El método respondDecisionTaskCompleted del cliente de SWF toma el token de la tarea que identifica la tarea, así como la lista de objetos Decision.

Implementación del iniciador del flujo de trabajo

Por último, escribiremos código para iniciar la ejecución del flujo de trabajo.

  1. Abra su editor de texto y cree el archivo WorkflowStarter.java, añadiendo una declaración del paquete y funciones import de acuerdo con los pasos comunes.

  2. Añada la clase 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() + "'."); } }

    La clase WorkflowStarter consta de un único método, mainque toma un argumento opcional pasado en la línea de comandos como datos de entrada para el flujo de trabajo.

    El método de cliente SWF toma un StartWorkflowExecutionRequestobjeto como entrada. startWorkflowExecution Aquí, además de especificar el dominio y tipo de flujo de trabajo que se va a ejecutar, proporcionamos:

    • Un nombre de ejecución de flujo de trabajo en lenguaje natural

    • Los datos de entrada del flujo de trabajo (proporcionados en la línea de comandos en nuestro ejemplo)

    • Un valor de tiempo de espera que representa cuánto tiempo, en segundos, debe tardar en ejecutarse todo el flujo de trabajo

    El objeto Run que startWorkflowExecution devuelve proporciona un identificador de ejecución, un valor que se puede utilizar para identificar la ejecución de este flujo de trabajo concreto en el historial Amazon SWF de ejecuciones del flujo de trabajo.

    + NOTA: El ID de ejecución lo genera el nombre de Amazon SWF ejecución del flujo de trabajo que se introduce al iniciar la ejecución del flujo de trabajo, y no es el mismo que el mismo.

Compilación del ejemplo

Para crear el proyecto de ejemplo con Maven, vaya al directorio helloswf y escriba:

mvn package

El helloswf-1.0.jar resultante se generará en el directorio target.

Ejecutar el ejemplo

El ejemplo consta de cuatro clases ejecutable distintas, que se ejecutan de forma independiente entre sí.

nota

Si utiliza un sistema Linux, macOS o Unix, puede ejecutarlas todas ellas, una detrás de otra, en una sola ventana del terminal. Si ejecuta Windows, debe abrir dos instancias de línea de comandos adicionales e ir al directorio helloswf de cada una de ellas.

Definición del classpath Java

Aunque Maven ha gestionado las dependencias por ti, para ejecutar el ejemplo, tendrás que proporcionar la biblioteca del AWS SDK y sus dependencias en tu ruta de clases de Java. Puedes configurar la variable de CLASSPATH entorno en la ubicación de las bibliotecas del AWS SDK y en el third-party/lib directorio del SDK, que incluye las dependencias necesarias:

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

O puede usar la opción -cp del comando java para establecer el classpath mientras se ejecuta cada una de las aplicaciones.

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

Usted decide el método que desea utilizar. Si no has tenido problemas para compilar el código, intenta ejecutar los ejemplos y obtendrás una serie de errores de tipo «NoClassDefFound», probablemente se deba a que la ruta de clases no está configurada correctamente.

Registro del dominio y de los tipos de flujo de trabajo y actividad

Antes de ejecutar sus procesos de trabajo y el iniciador del flujo de trabajo, tendrá que registrar el dominio y sus tipos de flujo de trabajo y actividad. El código para esto se ha implementado en la sección Registro de un dominio y de tipos de flujo de trabajo y actividad.

Después de la compilación, si ha establecido el CLASSPATH, puede ejecutar el código de registro ejecutando el comando:

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

Inicio de los procesos de trabajo de actividad y flujo de trabajo

Ahora que los tipos se han registrado, puede iniciar los procesos de trabajo de actividad y flujo de trabajo. Estos se seguirán ejecutando y buscarán tareas hasta que se cancelen, por lo que deberá ejecutarlos en ventanas de terminal diferentes o, si utiliza Linux, macOS o Unix, puede usar el operador & para hacer que cada uno de ellos genere un proceso distinto cuando se ejecuten.

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

Si ejecuta estos comandos en ventanas distintas, omita el operador & al final de cada línea.

Inicio de la ejecución del flujo de trabajo

Ahora que los procesos de trabajo de actividad y flujo de trabajo están realizando operaciones de sondeo, puede iniciar la ejecución del flujo de trabajo. Este proceso se ejecutará hasta que el flujo de trabajo devuelva un estado completado. Debe ejecutarlo en una nueva ventana de terminal (a menos que ejecute sus procesos de trabajo como nuevos procesos generados mediante el operador &).

fi
nota

Si desea proporcionar sus propios datos de entrada, que se pasarán primero al flujo de trabajo y después a la actividad, añádalos a la línea de comandos. Por ejemplo:

echo "## Running $className..."

Una vez que comience la ejecución del flujo de trabajo, debería empezar a ver los resultados enviados por ambos procesos de trabajo y por la propia ejecución del flujo de trabajo. Cuando el flujo de trabajo termine de completarse, el resultado se mostrará en la pantalla.

Código fuente completo de este ejemplo

Puedes buscar el código fuente completo de este ejemplo en Github, en el aws-java-developer-guiderepositorio.

Para obtener más información