AWS SWF Promise IllegalStateException: не готов

Я пытаюсь выполнить рабочий процесс 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
}

Предполагается, что приведенный выше код перезапускает рабочий процесс при выполнении определенных условий. Условия зависят от значений, заполненных в экземпляре 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 будет заполнен и возвращен методом активности, прежде чем продолжить.


person learningMyWayThru    schedule 24.08.2016    source источник
comment
Я обнаружил, что эта конкретная ошибка чаще всего возникает, когда аннотации AspectJ или SWF настроены неправильно. Это довольно раздражает таким образом...   -  person Krease    schedule 24.08.2016
comment
Как вы определили, какие аннотации были настроены неправильно? Я удалил возможности AspectJ для проекта, а затем снова добавил их. Все еще получаю ту же ошибку. Если я вызываю метод активности только один раз (т.е. удаляю путь кода после первого вызова метода активности), код работает.   -  person learningMyWayThru    schedule 24.08.2016
comment
Как Вы определили, какие аннотации были настроены неправильно? Много боли. Просеивание документов, чтобы проверить и перепроверить. SWF, требующий AspectJ, делает его отладку огромной проблемой. Извините, я больше ничем не могу помочь.   -  person Krease    schedule 24.08.2016
comment
Используйте Task вместо @Asynchronous. Это выглядит уродливее, но не полагается на AspectJ.   -  person Maxim Fateev    schedule 24.08.2016


Ответы (1)


Аннотации SWF настроены неправильно. Из-за этих проблем @Asynchronous не работает должным образом.

Чтобы добавить AspectJ в качестве агента Java

  1. Чтобы открыть диалоговое окно «Настройки», щелкните «Окно» > «Настройки».
  2. Перейдите к Java > Установленные JRE.
  3. Выберите соответствующую JRE и нажмите «Изменить».
  4. В поле Аргументы виртуальной машины по умолчанию введите путь к установленному двоичному файлу AspectJ. Это будет путь, например, /home/user/aspectj1.7/lib/aspectjweaver.jar, в зависимости от вашей операционной системы и загруженной версии AspectJ.

В Linux, OS X или Unix используйте:

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

Вместо этого в Windows используйте стандартный путь в стиле Windows:

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

Чтобы настроить AspectJ для AWS Flow Framework для 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.*. Используйте значение, подходящее для пакетов вашего собственного проекта.

person Nithin K Anil    schedule 13.09.2016