2016-04-15 2 views
1

Когда я отправлял сообщения в компоненте коннектора Camel на свою конечную точку, мне нужно ждать ответного сообщения с подтверждением. Если ответ не получен в течение таймаут-времени, исключение должно быть возвращено на маршрут верблюда.Apache Camel: Как передавать исключения через конечную точку SEDA?

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

Так что у меня следующий маршрут:

private final String internalRespUri = "direct:internal_resp"; 
private final String internalRespTimeout = "seda:internaltimeout"; 

@Override 
public void configure() { 
    SendController send_controller = new SendController(); 
    TimeoutResponse resp = new TimeoutResponse(); 

    from(Endpoints.MESSAGE_IN.direct()) 
        .errorHandler(noErrorHandler()) 
        .routeId(Endpoints.MESSAGE_IN.atsm()) 
        .log("Incoming message at segment in") 
        .process(send_controller) 
        .log("Message after send controller") 
        .multicast().parallelProcessing() 
        .log("After wiretap") 
        .to(internalRespTimeout, Endpoints.SEGMENT_OUT.direct()); 
    from(internalRespTimeout) 
        .errorHandler(noErrorHandler()) 
        .routeId(internalRespTimeout) 
        .log("begin response route") 
        .log("timeout response route") 
        .process(resp) 
        .log("modify message to response") 
        .delay(1000) 
        .log("after delay") 
        .to(internalRespUri); 
    from(Endpoints.SEGMENT_IN.seda()) 
        .routeId(Endpoints.SEGMENT_IN.atsm()) 
        .to(internalRespUri); 
    from(internalRespUri) 
        .errorHandler(noErrorHandler()) 
        .routeId(internalRespUri) 
        .log("after response gathering point") 
        .choice() 
        .when(header(HeaderKeys.TYPE.key()).isEqualTo(UserMessageType.RESP.toString())) 
        .log("process responses") 
        .process(send_controller) 
        .otherwise() 
        .log("no response") 
        .to(Endpoints.MESSAGE_OUT.direct()); 
} 

Проблема заключается в том, что исключение брошено в SendController не распространяется по SEDA конечной internalRespTimeout. Если я использую прямую конечную точку вместо этого, она работает, но тогда у меня есть другая проблема: Задержка блокирует маршрут, в то время как полученное ответное сообщение от конечной точки Endpoints.SEGMENT_IN.seda() не может быть передано.

Являются ли конечные точки SEDA вообще не способными распространять исключения? Как я могу решить проблему?

Спасибо, Sven

ответ

0

У меня есть идея:

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

Могло ли это работать?

0

В настоящее время я не знаю способ распространения и исключения обратно на конечную точку SEDA на верблюде. Способ обработки ошибок основан на каналах между конечными точками. Когда вы используете конечную точку SEDA, код будет продолжать обрабатывать и не ждать кода, так как он будет продолжать обработку. У меня возникли проблемы с пониманием того, что вы хотели бы выполнить, но я расскажу о некоторых аналогичных альтернативах, которые вы могли бы использовать.

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

- Во-вторых, чтобы передать данные в Java Bean, где вы полностью контролируете свои действия и можете даже подумать над тем, как использовать фьючерсы Guava для асинхронного запуска кода при выполнении других задач.

Если вы можете объяснить, что вы пытаетесь сделать немного лучше, я мог бы сделать более ясное предложение.

+0

То, что я пытаюсь достичь, - это реализовать внутренний протокол моей компании в компоненте контекста Camel, который будет использоваться в качестве библиотеки в разных приложениях. Затем он может использоваться как Blackbox с 4 конечными точками. – Sven

+0

Когда сообщения должны быть упакованы протоколом, каждое сообщение отправляется в конечную точку Endpoints.MESSAGE_IN.direct(). В контексте компонента протокол sppplits сообщение в сегментах и ​​отправить его через Endpoints.SEGMENT_OUT.direct(). Когда сегменты принимаются от партнера, он отправляет ответные сообщения с кодами состояния. Via Endpoints.SEGMENT_IN.direct(). Затем я интерпретирую коды состояния и поведение тайм-аута, если ответ от партнера не получен. – Sven

+0

Проблема в том, как отправить исключение, если нет или ответ об ошибке получен? ИТ следует размножать на маршруте к вызывающей стороне конечной точки Endpoints.MESSAGE_IN.direct().Поскольку исходное сообщение уже отправлено, верблюд не знает, как реагировать на исключение и где его распространять. – Sven

Смежные вопросы