Весенняя интеграция: рекурсивный поток? - PullRequest
1 голос
/ 27 января 2020

Я новичок в Spring / Spring Integration и у меня возникли проблемы с пониманием того, как правильно реализовать поток, который допускает переменное количество исходящих вызовов шлюза.

Проблема: Учитывая идентификатор клиента, я делаю один вызов исходящего шлюза, чтобы получить список связанных клиентов. Для каждого из этих связанных клиентов мне нужно сделать еще один вызов исходящего шлюза.

Мой первоначальный подход: После первого вызова службы я заполняю очередь полученными идентификаторами related-customer, вызываю вспомогательный метод для опроса очереди, затем продолжаю поток, вызывая исходящий шлюз снова для выполнения следующего запроса (только если остался клиент). После получения ответа шлюз затем вызывает тот же вспомогательный метод, который повторяет процесс.

Если очередь пуста, заголовок используется для направления потока к logAndReply внутри вспомогательного метода (см. Код ниже).

private IntegrationFlow helperMethod()
{
    return flow -> flow

        .transform(payload -> {
            currentCust = info.poll();
            return payload;
        })

        //check if there is another related-customer to process
        .handle(
                (payload, headers) -> MessageBuilder
                        .withPayload(payload)
                        .copyHeaders(headers)
                        .setHeader("relatedCustomerLeft", (null == currentCust ? Boolean.FALSE : Boolean.TRUE))
                        .build()
        )
        .route(("headers['relatedCustomerLeft']"), route -> route

                //if no more related-customers, end the flow
                .subFlowMapping(Boolean.FALSE,
                        subFlow -> subFlow
                            .logAndReply(LoggingHandler.Level.INFO, "end of base case")
                )
                //if there is a related customer, call the gateway
                .subFlowMapping(Boolean.TRUE,
                        subGateway()
                )
        );
}

Здесь subGateway () просто возвращает другой IntegrationFlow, который обрабатывает исходящий вызов службы. Эта логика c, кажется, работает, когда я удаляю рекурсивные вызовы. Однако включение рекурсивных вызовов вызывает ошибку переполнения стека при запуске. Журнал просто показывает «Создание SAAJ 1.3 MessageFactory с протоколом SOAP 1.1» снова и снова, пока не произойдет переполнение стека.

"Исключительная ситуация при инициализации контекста - отмена refre sh попытка: org.springframework.beans.factory.BeanCreationException: Ошибка создания компонента с именем 'getFlow', определенным в файле [GetFlow.class]: Не удалось инициализировать bean-компонент; вложенное исключение - java .lang.StackOverflowError "

Мои вопросы

  1. Почему произойдет переполнение стека?
  2. Возможна ли рекурсия так, как я ее пытаюсь использовать? Как правильно его реализовать?
  3. Есть ли лучший способ go сделать переменное число вызовов шлюза? Есть примеры?

Как я уже сказал, я все еще новичок, поэтому любые советы или ресурсы также будут высоко оценены.

1 Ответ

1 голос
/ 28 января 2020

Во-первых, вы не показываете, как вы создаете эту рекурсию, во-вторых, неясно, зачем вообще нужна рекурсия в вашем сценарии использования.

Звучит так, как будто вам нужна enrich() «получить список связанных клиентов». Затем вам нужно split() против этого возвращенного списка клиентов, чтобы вызвать услугу для каждого из них. И кажется для меня это все! Никакой рекурсии не требуется.

Я также хотел бы иметь filter() до split(), чтобы убедиться, что список не пуст. Или route(), как вы уже ...

Но все еще неясно, откуда взялась бы эта рекурсия ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...