本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
构建一个简单的Amazon SWF应用程序
本主题将向您介绍使用对Amazon SWF
关于示例
该示例项目将创建一个包含单一活动的工作流程,该活动接受通过AWS云端传递的工作流程数据(传统上HelloWorld,这是要打招呼的人的名字),然后打印问候语作为回应。
虽然表面上看起来这非常简单,不过 Amazon SWF 应用程序由多个协同工作的部件组成:
-
一个域,用作工作流执行数据的逻辑容器。
-
一个或多个工作流程,它们表示代码组件,这些组件定义工作流程的活动和子工作流程执行的逻辑顺序。
-
一个工作流工作线程,也称为决策程序,轮询决策任务并在响应中计划活动或子工作流。
-
一个或多个活动,每个活动表示工作流中的一个工作单元。
-
一个活动工作线程,轮询活动任务并在响应中运行活动方法。
-
一个或多个任务列表,这是由 Amazon SWF 维护的队列,用于发布请求到工作流和活动工作线程。任务列表上用于工作流工作线程的任务称为决策任务。用于活动工作线程的任务称为活动任务。
-
一个工作流启动程序,用于开始工作流的执行。
在幕后,Amazon SWF协调这些组件的操作,协调它们来自AWS云的流程,在它们之间传递数据,处理超时和心跳通知,并记录工作流程执行历史记录。
先决条件
开发环境
此教程中使用的开发环境包括:
-
Apache Maven
(3.3.1)。 -
JDK 1.7 或更高版本。本教程使用 JDK 1.8.0 开发和测试。
-
一个适用的 Java 文本编辑器 (由您选择)。
注意
如果您使用与 Maven 不同的构建系统,您仍然可以使用适合您的环境的相应步骤来创建项目,并使用此处提供的概念进行操作。AWS SDK for Java入门中提供了在不同编译系统中配置和使用 的更多信息。
同样,但只要付出更多的努力,就可以使用支持的任何 AWS SDK 来实现此处显示的步骤。Amazon SWF
所有必需的外部依赖项包括在 AWS SDK for Java 中,因此无需下载其他内容。
AWS存取
要成功完成本教程,您必须具有访问门户的AWS权限,如本指南的基本设置部分所述。
这些说明描述了如何访问您复制并粘贴到本地共享credentials
文件中的临时证书。您粘贴的临时证书必须与有权访问 Amazon SWF 的 IAM 角色相关联。AWS IAM Identity Center (successor to AWS Single Sign-On)粘贴后,将credentials
类似于以下内容。
[default] aws_access_key_id=AKIAIOSFODNN7EXAMPLE aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY aws_session_token=IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZVERYLONGSTRINGEXAMPLE
这些临时证书与default
配置文件相关联。
创建 SWF 项目
-
使用 Maven 启动新项目:
mvn archetype:generate -DartifactId=helloswf \ -DgroupId=aws.example.helloswf -DinteractiveMode=false
这将创建具有标准 maven 项目结构的新项目:
helloswf ├── pom.xml └── src ├── main │ └── java │ └── aws │ └── example │ └── helloswf │ └── App.java └── test └── ...
您可以忽略或删除
test
目录及其中包含的所有内容,我们不会将其用于此教程。您还可以删除App.java
,因为我们将使用新类来替换它。 -
编辑项目的
pom.xml
文件,然后通过在块中添加aws-java-sdk-simpleworkflow模块的依赖关系来添加该模<dependencies>
块。<dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-simpleworkflow</artifactId> <version>1.11.1000</version> </dependency> </dependencies>
-
确保 Maven 使用 JDK 1.7+ 支持构建您的项目。将以下内容添加到您项目 (在
<dependencies>
块之前或之后) 的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>
编码项目
示例项目包括四个独立的应用程序,我们将逐个查看:
-
HelloTypes.java--包含与其他组件共享的项目域、活动和工作流程类型数据。它还处理这些类型在 SWF 中的注册。
-
ActivityWorker.java--包含活动工作器,它轮询活动任务并运行活动作为响应。
-
WorkflowWorker.java--包含工作流程工作者(决策者),它轮询决策任务并安排新活动。
-
WorkflowStarter.java--包含工作流程启动器,它会启动新的工作流程执行,这将导致 SWF 开始生成决策和工作流程任务供您的工作人员使用。
所有源文件的常见步骤
您创建的用于托管 Java 类的所有文件都有几个共同点。出于时间考虑,这些步骤在每次添加新文件到项目时是隐含的:
-
在项目的
src/main/java/aws/example/helloswf/
目录中创建文件。 -
添加
package
声明到每个文件的开头用于声明其命名空间。示例项目使用:package aws.example.helloswf;
-
为该AmazonSimpleWorkflowClient类和
com.amazonaws.services.simpleworkflow.model
命名空间中的多个类添加import
声明。为了简化操作,我们使用:import com.amazonaws.regions.Regions; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder; import com.amazonaws.services.simpleworkflow.model.*;
注册域、工作流程和活动类型
我们将从创建新的可执行类 HelloTypes.java
开始。此文件将包含共享数据,您的工作流中的不同部分需要这些数据,例如活动的名称和版本以及工作流类型,域名和任务列表名称。
-
打开文本编辑器并创建文件
HelloTypes.java
,添加程序包声明并根据通用步骤导入。 -
声明
HelloTypes
类并向其提供值,以供注册的活动和工作流类型使用: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";
这些值将在代码中使用。
-
在 String 声明之后,创建该AmazonSimpleWorkflowClient类的实例。这是由AWS SDK for Java向 Amazon SWF 方法提供的基本接口。
private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
前面的代码片段假设临时证书与
default
配置文件相关联。如果您使用不同的配置文件,请按如下方式修改上面的代码,并将profile_nam
e 替换为实际配置文件名称的名称。private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder .standard() .withCredentials(new ProfileCredentialsProvider("
profile_name
")) .withRegion(Regions.DEFAULT_REGION) .build(); -
添加新函数以注册到 SWF 域。域 是多种相关 SWF 活动和工作流类型的逻辑容器。SWF 组件只有在位于同一个域中时才能彼此通信。
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!"); }
注册域时,您需要为其提供名称(不包括、
:
、/
、控制字符或字面字符串 '`arn' 以外的任意一组 1-256 个字符)和保留期,即Amazon SWF工作流程执行完成后保留工作流程执行历史数据的天数。|
最长的工作流执行保留期为 90 天。有关RegisterDomainRequest更多信息,请参阅。如果同名域名已经存在,则引DomainAlreadyExistsException发 a。因为我们并不关注是否已经创建了域,因此可以忽略此异常。
注意
此代码演示了使用AWS SDK for Java方法时的一个通用模式,方法的数据由
simpleworkflow.model
命名空间中的类提供,该命名空间使用可链接的0—with*
方法实例化和填充。 -
添加函数以注册新活动类型。活动 表示工作流中的一个工作单元。
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!"); }
活动类型由名称和版本标识,它们在所注册到的域中用于将活动与任何其他活动区分开。活动还包含多种可选参数,例如用于从 SWF 接收任务和数据的默认任务列表,以及您可用来对活动各个部分执行所用时长施加限制的不同超时。有关RegisterActivityTypeRequest更多信息,请参阅。
注意
所有超时值以秒 为单位指定。有关Amazon SWF超时如何影响工作流程执行的完整描述,请参阅超时类型。
如果您尝试注册的活动类型已经存在,TypeAlreadyExistsException则会引发。添加函数以注册新工作流类型。工作流程 也称为决策程序,表示工作流程执行的逻辑。
+
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!"); }
+
与活动类型类似,工作流类型由名称 和版本 标识,也具有可配置的超时。有关RegisterWorkflowTypeRequest更多信息,请参阅。
+
如果您尝试注册的工作流程类型已经存在,TypeAlreadyExistsException则会引发。最后,请通过向类提供 main
方法确保其可执行,这反过来会注册域、活动类型和工作流类型:
+
registerDomain(); registerWorkflowType(); registerActivityType();
现在,您可以编译并运行应用程序来运行注册脚本,或者继续对活动和工作流工作线程编写代码。一旦注册了域、工作流程和活动,您就无需再次运行它们,这些类型会一直存在,直到您自己将其弃用。
实施活动工作线程
活动 是工作流中的基本工作单元。工作流提供逻辑、要运行的计划活动 (或要采取的其他操作) 来响应决策任务。典型的工作流通常包含多种活动,可以同步、异步或者以两种方式结合运行。
活动工作线程 是一段代码,轮询由 Amazon SWF 生成的活动任务来响应工作流决策。在收到活动任务时,它将运行对应的活动并将成功/失败响应返回到工作流。
我们将实施驱动单个活动的简单活动工作线程。
-
打开文本编辑器并创建文件
ActivityWorker.java
,添加程序包声明并根据通用步骤导入。import com.amazonaws.regions.Regions; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder; import com.amazonaws.services.simpleworkflow.model.*;
-
向文件中添加
ActivityWorker
类,并向其提供数据成员以保存用来与 Amazon SWF 交互的 SWF 客户端:private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
-
添加将用作活动的方法:
private static String sayHello(String input) throws Throwable { return "Hello, " + input + "!"; }
该活动就是获取字符串,将其组合到问候语中,然后返回结果。虽然此活动有很小的可能性会引发异常,但最好的做法是将活动设计为在出现问题时会引发错误。
-
添加我们将用作活动任务轮询方法的
main
方法。我们首先添加一些代码来轮询任务列表中的活动任务: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();
活动Amazon SWF通过调用 SWF 客户端
pollForActivityTask
的方法,指定传入中要使用的域和任务列表来接收任务。PollForActivityTaskRequest一旦收到任务,我们将通过调用任务的
getTaskToken
方法来检索它的唯一标识符。 -
接下来,写入一些代码来处理传入的任务。将以下内容添加到您的
main
方法,就在轮询任务和检索其任务令牌代码的后方。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())); } }
如果任务令牌不是
null
,则我们可以开始运行活动方法 (sayHello
),只要它具有随任务发送的输入数据。如果任务成功(未生成错误),则工作程序通过使用包含任务令牌和活动结果数据的RespondActivityTaskCompletedRequest对象调用 SWF 客户端的
respondActivityTaskCompleted
方法来响应 SWF。另一方面,如果任务失败,那么我们通过使用RespondActivityTaskFailedRequest对象调用
respondActivityTaskFailed
方法,向其传递任务令牌和有关错误的信息来响应。
注意
如果终止,此活动不会正常关闭。虽然这超出了本教程的范围,不过在相关主题适当地关闭活动和工作流工作线程中提供了此活动工作线程的替代实施方法。
实施工作流工作线程
您的工作流逻辑位于称为工作流工作线程的代码块中。工作流工作线程在工作流类型注册到的默认任务列表上,轮询域中 Amazon SWF 发送的决策任务。
工作流工作线程接收任务时,它会做出某种类型的决策 (通常为是否计划新活动) 并采取相应操作 (例如计划活动)。
-
打开文本编辑器并创建文件
WorkflowWorker.java
,添加程序包声明并根据通用步骤导入。 -
将一些额外的导入添加到文件中:
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;
-
声明该
WorkflowWorker
类,并创建用于访问 SWF 方法的AmazonSimpleWorkflowClient类的实例。private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
-
添加
main
方法。该方法持续循环,使用 SWF 客户端的pollForDecisionTask
方法轮询决策任务。PollForDecisionTaskRequest提供了详细信息。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(); } } }
在收到任务之后,我们调用其
getTaskToken
方法,这会返回可用于标识任务的字符串。如果返回的令牌不是null
,那么我们在executeDecisionTask
方法中对其进行进一步处理,将任务令牌和随任务一起发送的HistoryEvent对象列表传递给它。 -
添加
executeDecisionTask
方法,获取任务令牌 (String
) 和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;
我们还可以设置一些数据成员来跟踪内容,例如:
-
用于报告任务处理结果的决策对象列表。
-
用于存储 “WorkflowExecutionStarted” 事件提供的工作流程输入的字符串
-
已计划和打开 (正在运行) 活动的计数,用于避免再次计划已经计划或者当前正在运行的相同活动。
-
用于指示活动已完成的布尔值。
-
用于保存活动结果的字符串,以将其作为我们的工作流结果返回。
-
-
接下来,添加一些代码到
executeDecisionTask
,基于HistoryEvent
方法报告的事件类型处理随任务发送的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("]");
对于我们的工作流,我们最感兴趣的是:
-
“WorkflowExecutionStarted” 事件,表示工作流程执行已开始(通常意味着您应该运行工作流程中的第一个活动),并提供给工作流的初始输入。在这种情况下,这是我们问候语的名称部分,因此将其保存在字符串中以在计划活动运行时使用。
-
“ActivityTaskCompleted” 事件,在预定活动完成后发送。事件数据还包括已完成活动的返回值。因为我们仅有一个活动,我们将使用该值作为整个工作流程的结果。
其他事件类型在工作流需要时可以使用。有关每种事件类型的信息,请参阅HistoryEvent类描述。
+ 注意:
switch
语句中的字符串是在 Java 7 中引入的。如果您使用的是早期版本的 Java,则可以使用该EventType类将String
返回的值history_event.getType()
转换为枚举值,然后在String
必要时将其转换回: -
EventType et = EventType.fromValue(event.getEventType());
-
在
switch
语句之后,添加更多代码,根据所收到的任务采用合适的决策 进行响应。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);
-
如果尚未安排活动,我们会做出
ScheduleActivityTask
决定,该决定以ScheduleActivityTaskDecisionAttributes结构形式提供有关接下来Amazon SWF应安排的活动的信息,还包括Amazon SWF应发送给该活动的所有数据。 -
如果活动已完成,则我们认为整个工作流程已完成,然后做出
CompletedWorkflowExecution
决定,填写CompleteWorkflowExecutionDecisionAttributes结构以提供有关已完成工作流程的详细信息。在这种情况下,我们将返回活动的结果。
在任何一种情况下,决策信息将添加到在方法顶部声明的
Decision
列表。 -
-
返回在处理任务时收集的
Decision
对象列表来完成决策任务。在我们所编写的executeDecisionTask
方法尾部添加此代码:swf.respondDecisionTaskCompleted( new RespondDecisionTaskCompletedRequest() .withTaskToken(taskToken) .withDecisions(decisions));
SWF 客户端的
respondDecisionTaskCompleted
方法获取标识任务的任务令牌以及Decision
对象列表。
实施工作流启动程序
最后,我们将编写一些代码用于启动工作流程执行。
-
打开文本编辑器并创建文件
WorkflowStarter.java
,添加程序包声明并根据通用步骤导入。 -
添加
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() + "'."); } }
WorkflowStarter
类包含一个方法main
,它获取命令行上传递的可选参数作为工作流的输入数据。SWF 客户端方法将StartWorkflowExecutionRequest对象作为输入。
startWorkflowExecution
此处,除了指定要运行的域和工作流类型之外,我们提供了:-
便于阅读的工作流执行名称
-
工作流输入数据 (我们的示例中在命令行上提供)
-
超时值,以秒为单位,表示整个工作流运行所应使用的时长。
返回的运行
startWorkflowExecution
对象提供了运行 ID,这是用于在 Amazon SWF 的工作流执行历史记录中标识此特定工作流执行的值。+ 注意:运行 ID 由生成Amazon SWF,与您在开始工作流程执行时传入的工作流程执行名称不同。
-
编译示例
要使用 Maven 编译示例项目,请转到 helloswf
目录并键入:
mvn package
生成的 helloswf-1.0.jar
将在 target
目录中生成。
运行示例
示例包括四个独立的可执行类,彼此独立运行。
注意
如果您使用的是 Linux、macOS 或 Unix 系统,则可以在单个终端窗口中一个接一个地运行所有这些系统。如果您运行的是 Windows,则应该打开两个额外的命令行实例并分别导航到 helloswf
目录。
设置 Java 类路径
尽管 Maven 已经为您处理了依赖关系,但要运行该示例,您需要提供 AWS SDK 库及其对您的 Java 类路径的依赖关系。您可以将CLASSPATH
环境变量设置为 AWS SDK 库的位置和 SDK 中的third-party/lib
目录,其中包括必要的依赖关系:
export CLASSPATH='target/helloswf-1.0.jar:/path/to/sdk/lib/*:/path/to/sdk/third-party/lib/*' java example.swf.hello.HelloTypes
或者使用
java
命令的 -cp
选项在运行各个应用程序时设置类路径。
java -cp target/helloswf-1.0.jar:/path/to/sdk/lib/*:/path/to/sdk/third-party/lib/* \ example.swf.hello.HelloTypes
您使用的样式由您决定。如果你在构建代码时没有遇到任何问题,那么尝试运行示例并出现一系列 “NoClassDefFound” 错误,这可能是因为类路径设置不正确。
注册域、工作流程和活动类型
在运行工作线程和工作流程启动程序之前,您需要注册域以及工作流程和活动类型。执行此操作的代码是在注册域工作流程和活动类型中实现的。
在编译之后,如果您已设置 CLASSPATH,则可以通过执行以下命令运行注册代码:
echo 'Supply the name of one of the example classes as an argument.'
启动活动和工作流工作线程
现在类型已注册,您可以启动活动和工作流工作线程。它们会继续运行并轮询任务,直到它们被终止,所以你应该在不同的终端窗口中运行它们,或者如果你在 Linux、macOS 或 Unix 上运行,你可以使用&
运算符让每个任务在运行时生成一个单独的进程。
echo 'If there are arguments to the class, put them in quotes after the class name.' exit 1
如果您在单独窗口中运行这些命令,则忽略每一行最后的 &
运算符。
启动工作流执行
现在正在轮询您的活动和工作流工作线程,您可以启动工作流执行。此进程将运行直至工作流返回已完成状态。您应在新终端窗口中运行它 (除非您使用 &
运算符将工作线程作为新生成的进程运行)。
fi
注意
如果您要提供自己的输入数据 (这将首先传递到工作流,然后传递到活动),则将其添加到命令行中。例如:
echo "## Running $className..."
一旦开始工作流执行,您应该开始查看这两种工作线程以及工作流执行本身提供的输出。工作流最终完成之后,其输出将显示在屏幕上。
此示例的完整源代码
您可以在aws-java-developer-guide存储库的 Github 上浏览此示例的完整源代码
有关更多信息
-
如果在工作流轮询仍在进行时关闭此处提供的工作线程,则它们会导致任务丢失。要了解如何适当地关闭工作线程,请参阅适当地关闭活动和工作流工作线程。
-
要了解更多信息Amazon SWF,请访问Amazon SWF
主页或查看Amazon SWF开发者指南。 -
您可以使用 for AWS Flow Framework Java 使用注解以优雅的 Java 风格编写更复杂的工作流程。要了解更多信息,请参阅要了解更多信息,AWS Flow Framework请参阅《开发人员指南》。