2016-04-13 4 views
1

Edit: Um genau zu sein Ich denke, ich frage nach einer eleganten Möglichkeit, 2 Endpunkte zu spezifizieren, die ich 2 verschiedene Austäusche von einem Eingang von 1 Austausch senden möchte.Apache Camel - Was ist Camel am besten, um Fehler und gute Objekte gleichzeitig vom Komponentenendpunkt zu senden?

Ich weiß Camel ‚kann‘ dies tun - aber ich habe nur unelegant Methoden, bei denen ein Objekt sendet, die beiden Typen an eine Multicast() und Prozessoren auf jedem Abschnitt


ich dort erwarte Entfernen enthält sein möglicherweise mehrere Fehlermeldungen mit angehängten Quellobjekten. Ich könnte sie einfach als Ausnahmen werfen, aber das fühlt sich falsch an. Ich frage mich, was der "richtige" Ansatz sein könnte. Ich möchte fast nur in der Lage sein einen Fehler Endpunkt als Ziel für meine Komponente angeben

Zur Zeit habe ich

camel.addComponent("my", new MyComponent()) 


from(some source) 
... processing // Lists of input objects as body of in 
... onException() 
.to("my:endpoint") 

MyComponent < - MyEndpoint < - MyProducer

Ich möchte das verarbeiten Elemente in jedem List-Objekt, das bei MyProducer eintrifft. Ich verarbeite die Elemente und sende fehlerhafte Objekte an einen Endpunkt, und gute Objekte an einen Endpunkt.

Ich sehe keinen guten/eleganten Weg, dies zu erreichen. Wenn es einzelne Elemente (d. H. Keine Sammlung) war, kann ich einfach eine Ausnahme auslösen und sie in einem onException-Stream abfangen.

Aber ich möchte wirklich in der Lage sein, Gegenstände zu nehmen, und gute Gegenstände zu trennen und sie in eine Richtung und schlechte Gegenstände zu senden und ihnen einen anderen zu schicken.

Mit anderen Worten, ich möchte gleichzeitig 2 verschiedene Nachrichten an 2 verschiedene Endpunkte von der gleichen Eingabe von einem Endpunkt senden. (Der Endpunkt ist hier eigentlich nicht so wichtig, ich schreibe einen, es könnte jeder Prozessor sein).

Ich weiß, ich könnte ein zerlegbares Objekt mit guten und schlechten Objekten erstellen, dann Multicast und jede gute und schlechte Sektion auf verschiedenen Stücken verarbeiten, aber ich hätte gerne einen prägnanten wiederverwendbaren Mechanismus (zB eingebaut in einen Prozessor oder Endpunkt)

+0

Sie sagen, dass "ich sehe keine gute/elegante Weise, dies zu erreichen, für einzelne Elemente", aber sicherlich ist ein einzelnes Element nur eine Sammlung mit einem Element. Wie können Sie eine einzelne Nachricht sowohl an einen fehlgeschlagenen als auch an einen erfolgreichen Endpunkt senden? Kannst du ein bisschen klarstellen? – Namphibian

+0

Es ist einfach schlecht geschrieben, ich hätte lieber ein Semikolon als ein Komma setzen sollen. Es sollte eine Pause sein –

+0

umgeschrieben jetzt um klarer zu sein –

Antwort

1

In Camel ist das Zeug zwischen dem from() und dem to() ein Exchange, die als eine einzige Nachricht behandelt wird. Die Komponente sollte nur eine Factory für Endpoint Instanzen sein, die entweder Exchange erstellt oder sendet. Es sollte nicht die Nachricht verarbeiten (wie es hier klingt), also gibt es nicht wirklich ein Konzept von Fehlern oder guten Objekten, das ist für die Route und die Processors/Beans zu entscheiden.

Wenn Sie alles innerhalb eines einzigen Austauschs tun möchten, können Sie Ihrem Prozessor einfach zwei Listen hinzufügen, um Eigenschaften auszutauschen und sie basierend auf dem Inhalt zu routen.

from("direct:somesource") 
    .process(new Processor() { 
     public void process(Exchange exchange) { 
      // get contents, 
      // turn it into a list 
      // 
      List<Object> worked = new ArrayList<>(); 
      List<Object> failed = new ArrayList<>(); 
      for (Object o : listFromBody) { 
       try { 
        // do work 
        worked.add(o); 
       } catch (Exception e) { 
        failed.add(o) 
       } 
      } 
      exchange.getIn().setProperty("worked", worked); 
      exchange.getIn().setProperty("failed", failed); 
     } 
    };) 
    .choice() 
      .when(header("failed").isNotEqualTo(null)) // might be a better way to do this, I've not got the IDE open 
       .process(turnFailedHeaderIntoMessageBody) 
       .to("direct:errorQueue") 
      .otherwise() 
       .process(turnWorkedHeaderIntoMessageBody) 
       .to("direct:workedQueue"); 

Das ist jedoch kein gutes Kamelmuster. Es ist unordentlich und versucht, die Eigenschaften als verschiedene Nachrichten zu behandeln, die entgegengesetzt sind, wie Kamel funktioniert. Aus der Perspektive der Route ist der Austausch eine atomare Einheit. Wenn Sie also die Nachricht aufbrechen müssen, ist es üblich, den Inhalt der Exchange als Exchange auf einer anderen Route zu verarbeiten.

Ich persönlich würde die Liste in separate Börsen aufgeteilt und einzeln wie folgt verarbeiten:

from("direct:somesource") 
    .split(body()) 
    .to("direct:processIndividualMessage"); 


from("direct:direct:processIndividualMessage") 
    .doTry() 
     .process(myProcessor) 
     .to("direct:goodQueue") 
    .doCatch(Exception.class) 
     .to("direct:errorQueue") 
    .end() 
0

Es ist alles auf dem Datenmodell abhängt. Aber Camel hat diesbezüglich keine Einschränkungen, das erreichen Sie sicherlich. Ich kann klären, wenn Sie eine bestimmte Frage haben.