2016-04-15 3 views
1

Wenn ich Nachrichten in einer Camel Context Component an ihren Endpunkt gesendet habe, muss ich auf eine Antwort mit Bestätigung warten. Wird innerhalb der Timeout-Zeit keine Antwort empfangen, wird eine Ausnahme auf die Kamelroute zurückgeworfen.Apache Camel: Wie kann man Ausnahmen über einen SEDA-Endpunkt übertragen?

Ich versuchte es die folgende Art und Weise zu implementieren: ich eine Multicast verwendet, um eine Timeout-Reaktion zu erzeugen, während die ursprüngliche Nachricht an den Endpunkt gesendet wird. Die Timeout-Antwort wird verzögert und wenn nach dieser Zeitüberschreitung keine Antwort mehr empfangen wird, wird eine Timeout-Ausnahme auf die Route zurückgeworfen.

So habe ich die folgende Route:

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

Das Problem ist, dass die in den SendController geworfen Ausnahme nicht über den SEDA Endpunkt internalRespTimeout ausbreitet. Wenn ich stattdessen einen direkten Endpunkt verwende, funktioniert es, aber dann habe ich ein anderes Problem: Die Verzögerung blockiert die Route, während eine empfangene Antwortnachricht vom Endpunkt Endpoints.SEGMENT_IN.seda() nicht übertragen werden kann.

Kann der SEDA-Endpunkt im Allgemeinen keine Ausnahmen verbreiten? Wie kann ich eine Lösung für mein Problem erreichen?

Danke, Sven

Antwort

0

Ich habe eine Idee:

Statt eine Ausnahme zu werfen, ich könnte möglicherweise Transaktionen für Timeout verwenden.

Könnte das funktionieren?

0

Ich bin zur Zeit nicht bekannt, einen Weg zurück über einen SEDA Endpunkt in Kamel zu propagieren und Ausnahme. Die Funktionsweise der Fehlerbehandlung basiert auf Kanälen zwischen Endpunkten. Wenn Sie einen SEDA-Endpunkt verwenden, wird der Code weiter verarbeitet und nicht auf den Code gewartet, da er weiter verarbeitet wird. Ich habe ein wenig Schwierigkeiten zu verstehen, was Sie erreichen möchten, aber ich werde einige ähnliche Alternativen auflisten, die Sie möglicherweise verwenden können.

-Das ist zunächst eine Route Level-Fehler-Handler in Ihrem SEDA basierend Route zu nutzen und speichern Sie die Ausnahme eine eindeutige Kennung, die Sie später nachschlagen können.

- Die zweite besteht darin, die Daten in eine Java Bean zu übertragen, wo Sie die volle Kontrolle darüber haben, was Sie tun, und vielleicht sogar einen Guava Futures verwenden, um den Code asynchron auszuführen, während andere Aufgaben ausgeführt werden.

Wenn Sie erklären, was Sie ein bisschen besser zu erreichen versuchen, könnte ich in der Lage sein, einen klaren Vorschlag zu machen.

+0

Was ich versuche zu erreichen, ist ein internes Protokoll meiner Firma in einer Camel Context Component zu implementieren, um als Bibliothek in verschiedenen Anwendungen verwendet zu werden. Dann könnte es als Blackbox mit 4 Endpunkten verwendet werden. – Sven

+0

Wenn Nachrichten mit dem Protokoll gepackt werden sollen, wird jede Nachricht an den Endpunkt Endpoints.MESSAGE_IN.direct() gesendet. In der Kontextkomponente gibt das Protokoll die Nachricht in Segmenten aus und sendet sie über Endpoints.SEGMENT_OUT.direct(). Wenn die Segmente vom Gegenstück empfangen werden, sendet sie Antwortnachrichten mit Statuscodes zurück.via Endpoints.SEGMENT_IN.direct(). Dann interpretiere ich die Statuscodes und das Timeout-Verhalten, wenn keine Antwort vom Gegenstück empfangen wird. – Sven

+0

Das Problem ist, wie man eine Ausnahme zurücksendet, wenn keine oder eine Fehlerantwort empfangen wird? IT sollte auf der Route an den Aufrufer von Endpunkt Endpoints.MESSAGE_IN.direct() weitergegeben werden.Da die ursprüngliche Nachricht bereits gesendet wurde, weiß camel nicht, wie auf eine Ausnahme reagiert werden soll und wo sie verbreitet werden soll. – Sven