AWS SWF Promise IllegalStateException:未准备好

时间:2016-08-24 00:49:10

标签: java amazon-web-services promise amazon-swf

我正在尝试执行SWF工作流程。我遇到了关于Promise对象状态的问题。我的代码结构如下:

WorkflowClientImpl.java中的方法:

  @Override
  public void doSomething() {
    new TryCatch() {

        @Override
        protected void doTry() throws Throwable {
            System.out.println("Workflow Started");
            Promise<SomeObject> someObject = activityClient.doAction(param1);
            if(someObject.isready()) {
                 boolean reDo = shouldRestartWorkflow(someObject);
                 if(reDo) {
                      Promise<Void> timer = decisionContextProvider.getDecisionContext().getWorkflowClock()
                        .createTimer(TimeUnit.MINUTES.toSeconds(5));
                      continueAsNew(timer, param1);
                 }
            }
        }

        @Override
        protected void doCatch(Throwable e) throws Throwable {
            System.err.printlnt("Error occured while workflow");
            throw new RuntimeException(e);
        }
    };
}    


@Asynchronous
private boolean shouldRestartWorkflow(@Wait Promise<SomeObject> someObject) {

    if(someObject.get().getVariable() > 1)
        return true;

    return false;
}

@Asynchronous
public void continueAsNew(Promise<Void> timer, String param1) {
    selfClient.execute(param1);
    // SelfClient is instance of TempWorkflowSelfClient
}

上述代码应该在满足某些条件时重新启动工作流程。条件取决于activity方法返回的SomeObject实例中填充的值。但是,代码shouldRestartWorkflow似乎永远不会被调用。

我试着为此写一个单元测试。以下是代码:

@Before
public void setUp() throws Exception {

    trace = new ArrayList<String>();
    // Register activity implementation to be used during test run
    TempActivitiesImpl activitiesImpl = new TempActivitiesImpl(null, null) {

        @Override
        public SomeObject doAction(String randomString) {
            trace.add("Test Case - " + randomString);
            SomeObject testObject = new SomeObject();
            testObject.setVariable(true);

            return testObject;
        }
    };
    workflowTest.addActivitiesImplementation(activityImpl);    //Instance to activity class
    workflowTest.addWorkflowImplementationType(WorkflowImpl.class);
}


 @Test
public void testWorkflowExecutionCall() throws Throwable {

    WorkflowClient workflow = workflowFactory.getClient("RandomString");
    Promise<Void> promise = workflow.execute("RandomString");

    List<String> expected = new ArrayList<String>();
    expected.add("Test Case - RandomString");

    AsyncAssert.assertEqualsWaitFor("Unexpected Result", expected, trace, promise);
}

上述测试用例有效。但是,如果我要删除if(someObject.isready())条件。我收到错误IllegalStateException: Not Ready。我能够确定在尝试执行shouldRestartWorkflow()调用时发生错误。

我做错了吗?据我所知,shouldRestartWorkflow()应该等到SomeObject被填充并由activity方法返回,然后继续。

1 个答案:

答案 0 :(得分:0)

SWF注释未正确设置。由于这个问题,@ Asynchronous无法正常工作。

将AspectJ添加为Java代理

  1. 要打开“首选项”对话框,请单击“窗口”&gt;偏好。
  2. 导航到Java&gt;已安装的JRE。
  3. 选择适当的JRE,然后单击“编辑”。
  4. 在“默认VM参数”框中,输入已安装的路径 AspectJ二进制文件。这将是一条如此的道路 /home/user/aspectj1.7/lib/aspectjweaver.jar,取决于你的 操作系统和您下载的AspectJ版本。
  5.   

    在Linux,OS X或Unix上使用:

    -javaagent:/your_path/aspectj/lib/aspectjweaver.jar
    
      

    在Windows上,请使用标准的Windows样式路径:

    -javaagent:C:\your_path\aspectj\lib\aspectjweaver.jar
    

    要为AWS Flow Framework for Java配置AspectJ,请将aop.xml文件添加到项目中。

    1. 添加aop.xml文件
    2. 在项目的src目录中,添加名为META-INF。
    3. 的目录
    4. 使用以下内容将名为aop.xml的文件添加到META-INF。
    5. <aspectj>
         <aspects>
            <!-- declare two existing aspects to the weaver -->
            <aspect name="com.amazonaws.services.simpleworkflow.flow.aspectj.AsynchronousAspect"/>
            <aspect name="com.amazonaws.services.simpleworkflow.flow.aspectj.ExponentialRetryAspect"/>
         </aspects>
         <weaver options="-verbose">
           <include within="<replaceable>MySimpleWorkflow.*</replaceable>"/>
         </weaver>
      </aspectj>
      

      值取决于您如何命名项目的包。上面的示例假定项目的包遵循模式MySimpleWorkflow。*。使用适合您自己项目包的值。