2016-08-24 27 views
2

我試圖執行SWF工作流程。我遇到了關於Promise對象狀態的問題。我的代碼strucutre是如下:AWS SWF Promise IllegalStateException:未準備好

方法在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 
} 

上面的代碼應該是在滿足一定條件下重新啓動工作流程。條件取決於由活動方法返回的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被填充並通過活動方法返回。

+0

當AspectJ或SWF註釋設置不正確時,我發現特別的錯誤經常發生。這是非常煩人的... – Krease

+0

你是如何確定哪些註釋設置不正確的?我刪除了項目的AspectJ功能,然後重新添加它們。仍然有相同的錯誤。如果我只調用activity方法一次(即在第一次調用activity方法後刪除代碼路徑),代碼就可以工作。 – learningMyWayThru

+0

「您是如何確定哪些註釋未正確設置的?」很多痛苦。篩選文檔以檢查並仔細檢查。 SWF需要AspectJ使調試成爲一個巨大的痛苦。對不起,我幫不了多。 – Krease

回答

0

SWF註釋設置不正確。由於這個問題@Asynchronous不能正常工作。

要添加的AspectJ作爲一個Java代理

  1. 打開Preferences對話框中,單擊窗口>首選項。
  2. 導航至Java>已安裝的JRE。
  3. 選擇合適的JRE並單擊編輯。
  4. 在默認VM參數框中,輸入已安裝的AspectJ二進制文件的路徑。這將是一個路徑,例如 /home/user/aspectj1.7/lib/aspectjweaver.jar,具體取決於您的操作系統 以及您下載的AspectJ版本。

在Linux,Mac OS X或Unix使用:

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

在Windows上,使用標準的Windows風格的路徑,而不是:

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

爲AWS Flow Framework配置AspectJ對於Java,將aop.xml文件添加到項目中。

  1. 要添加的文件aop.xml中
  2. 在項目的src目錄下,添加一個名爲META-INF目錄下。
  3. 將以下內容添加到名爲aop.xml的META-INF文件中。
<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。*。使用適合您自己項目的軟件包的值。