2016-08-24 1 views
2

Ich versuche, den SWF-Workflow auszuführen. Ich stoße auf ein Problem in Bezug auf den Zustand Promise Objekt. Mein Code strucutre ist wie folgt:AWS SWF-Versprechen IllegalStateException: Nicht bereit

Methods in 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 
} 

Der obige Code soll den Workflow neu zu starten, wenn bestimmte Bedingungen erfüllt sind. Die Bedingungen hängen von Werten ab, die in der von der Aktivitätsmethode zurückgegebenen Instanz von SomeObject ausgefüllt wurden. Der Code shouldRestartWorkflow scheint jedoch nie aufgerufen zu werden.

Ich habe versucht, einen Komponententest dafür zu schreiben. Unten ist der Code:

@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); 
} 

Der obige Testfall funktioniert. Jedoch wenn ich den if(someObject.isready()) Zustand entfernen würde. Ich bekomme den Fehler IllegalStateException: Not Ready. Ich konnte feststellen, dass der Fehler auftritt, wenn es versucht, den shouldRestartWorkflow() Aufruf auszuführen.

Mache ich etwas falsch? Soweit ich verstehe, sollte die shouldRestartWorkflow() warten, bis das SomeObject aufgefüllt und nach Aktivitätsmethode zurückgegeben wird, bevor Sie fortfahren.

+0

Ich finde, dass dieser bestimmte Fehler am häufigsten auftritt, wenn AspectJ oder die SWF-Anmerkungen nicht richtig eingerichtet sind. Es ist ziemlich nervig so ... – Krease

+0

Wie haben Sie festgestellt, welche Anmerkungen nicht richtig eingerichtet wurden? Ich habe die AspectJ-Funktionen für das Projekt entfernt und sie dann erneut hinzugefügt. Immer noch der gleiche Fehler. Wenn ich die Aktivitätsmethode nur einmal aufrufe (d. H. Den Codepfad nach dem ersten Aufruf der Aktivitätsmethode entferne), funktioniert der Code. – learningMyWayThru

+0

"Wie haben Sie festgestellt, welche Anmerkungen nicht richtig eingerichtet wurden?" Viel Schmerz. Durch die Dokumente scannen, um zu überprüfen und zu überprüfen. SWF, das AspectJ benötigt, macht das Debuggen zu einem großen Problem. Entschuldigung, ich kann nicht viel mehr helfen. – Krease

Antwort

0

Die SWF-Anmerkungen sind nicht ordnungsgemäß eingerichtet. Aufgrund dieser Probleme funktioniert @Asynchronous nicht richtig.

Um AspectJ als Agent Java hinzufügen

  1. das Dialogfeld zu öffnen, klicken Sie auf Fenster> Einstellungen.
  2. Navigieren Sie zu Java> Installierte JREs.
  3. Wählen Sie die entsprechende JRE aus und klicken Sie auf Bearbeiten.
  4. Geben Sie im Feld Standard-VM-Argumente den Pfad zur installierten AspectJ-Binärdatei ein. Dies ist ein Pfad wie /home/user/aspectj1.7/lib/aspectjweaver.jar, abhängig von Ihrem Betriebssystem und der von Ihnen heruntergeladenen Version von AspectJ.

Unter Linux, OS X oder Unix verwenden:

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

:

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

unter Windows ein Standard-Windows-style Pfad stattdessen verwenden Konfigurieren von AspectJ für AWS Flow Framework Fügen Sie für Java eine aop.xml-Datei zum Projekt hinzu.

  1. Um eine aop.xml Datei
  2. In Ihrem Projekt src Verzeichnis, fügen Sie ein Verzeichnis mit dem Namen META-INF hinzuzufügen.
  3. Fügen Sie eine Datei namens aop.xml zu META-INF mit dem folgenden Inhalt hinzu.
<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> 

Der Wert hängt davon ab, wie Sie Ihr Projekt Pakete nennen. Im obigen Beispiel wird davon ausgegangen, dass die Pakete des Projekts dem Muster MySimpleWorkflow. * Folgten. Verwenden Sie einen Wert, der für die Pakete Ihres eigenen Projekts geeignet ist.

Verwandte Themen