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-support
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 SWF
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:
-
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
-
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 eliminarApp.java
, ya que lo reemplazaremos por nuevas clases. -
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>
-
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>
) enpom.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:
-
Cree el archivo en el directorio
src/main/java/aws/example/helloswf/
del proyecto. -
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;
-
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.
-
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. -
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.
-
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 yprofile_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(); -
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*
-
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.
-
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.*;
-
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();
-
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.
-
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. PollForActivityTaskRequestUna vez que se recibe una tarea, recuperamos un identificador único llamando al método
getTaskToken
de la tarea. -
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).
-
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. -
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;
-
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();
-
Añada el método
main
. Este método se ejecuta en bucle continuamente en busca de tareas de decisión usando el métodopollForDecisionTask
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 elexecuteDecisionTask
método y le pasamos el token de la tarea y la lista de HistoryEventobjetos enviados con la tarea. -
Añada el método
executeDecisionTask
, tomando el token de tarea (String
) y la listaHistoryEvent
.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
-
-
A continuación, añada código a
executeDecisionTask
para procesar los objetosHistoryEvent
que se han enviado a la tarea, en función del tipo de evento notificado por el métodogetEventType
.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 loString
devuelto porhistory_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());
-
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. -
-
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étodoexecuteDecisionTask
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 objetosDecision
.
Implementación del iniciador del flujo de trabajo
Por último, escribiremos código para iniciar la ejecución del flujo de trabajo.
-
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. -
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,main
que 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
Para obtener más información
-
Los procesos de trabajo presentados aquí pueden ocasionar la pérdida de tareas si se cierran mientras se ejecuta un sondeo del flujo de trabajo. Para saber cómo cerrar correctamente los procesos de trabajo, consulte Cerrar correctamente los procesos de trabajo de actividad y flujo de trabajo.
-
Para obtener más información Amazon SWF, visita la página de Amazon SWF
inicio o consulta la Guía para Amazon SWF desarrolladores. -
Puede utilizar la versión AWS Flow Framework para Java para escribir flujos de trabajo más complejos en un elegante estilo Java mediante anotaciones. Para obtener más información, consulte la Guía para desarrolladores de AWS Flow Framework para Java.