2016-08-24 4 views
2

SWFワークフローを実行しようとしています。私はPromiseオブジェクトの状態に関する問題に遭遇しています。私のコードstrucutreは以下の通りです:WorkflowClientImpl.javaでAWS SWF Promise IllegalStateException:準備ができていません

方法:

@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の機能を削除し、それらを再追加しました。まだ同じエラーが発生しています。アクティビティメソッドを1回呼び出す(つまり、アクティビティメソッドの最初の呼び出しの後にコードパスを削除する)と、コードが機能します。 – learningMyWayThru

+0

"どのアノテーションが正しく設定されていないかを特定しましたか?"たくさんの痛み。チェックしてダブルチェックするためにドキュメントを覗いてください。 AspectJを必要とするSWFは、デバッグを非常に困難にします。申し訳ありません。 – Krease

答えて

0

SWFアノテーションが正しく設定されていません。この問題のため、@Asynchronousは正常に動作していません。

は、[環境設定]ダイアログボックスを開くにはJavaエージェント

  1. ようにAspectJを追加するには、[ウィンドウ]> [設定]をクリックします。
  2. Java> Installed JREにナビゲートします。
  3. 適切なJREを選択し、[編集]をクリックします。
  4. [デフォルトVM引数]ボックスに、インストール済みの AspectJバイナリへのパスを入力します。これは /home/user/aspectj1.7/lib/aspectjweaver.jarのようなパスで、ご使用の オペレーティングシステムとダウンロードしたAspectJのバージョンによって異なります。
  5. のLinux、OS X、またはUnix使用に

:Windowsでは

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

、代わりに標準のWindowsスタイルのパスを使用します。

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

AWS Flow Framework用にAspectJを設定するにはJavaの場合は、aop.xmlファイルをプロジェクトに追加します。

  1. は、META-INFというディレクトリを追加し、プロジェクトのsrcディレクトリでaop.xmlファイル
  2. を追加します。
  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。*に従っていることを前提としています。自分のプロジェクトのパッケージに適した値を使用します。

関連する問題