when using camel, you may use decomposition and aggregation, for example, when you send a large file to Message Queuing, you may need to decompose a file into several packages for file size limitations or efficiency considerations. Merge into a full file after receiving all the packages.
Decomposition will break up a message into several copies (messages), which can then be processed separately, such as:
To implement the decomposition functionality, you need to add splitdefinition to the routing definition, That is, to invoke the Processordefinition.split method, the split method is primarily to receive an expression object, and Org.apache.camel.Expression is an interface in which there is only one evaluate method:
Package Org.apache.camel;public interface Expression { <T> T Evaluate (Exchange Exchange, class<t> type) ;}
When calling the split method, the Evaluate method needs to return an object type that has certain rules (requirements), what the specific rules are, and see the following source code for a directory:
public static iterator<object> Createiterator (Object value, String delimiter, final Boolean allowemptyvalues) {//I F its a message than we want to iterate its bodyif (value instanceof message) {value = (message) value). GetBody (); if (value = = null) {return collections.emptylist (). iterator ();} else if (value instanceof iterator) {return (Iterator<o bject>) value;} else if (value instanceof iterable) {return ((iterable<object>) value). iterator ();} else if (Value.getclass (). IsArray ()) {if (Isprimitivearraytype (Value.getclass ())) {final Object array = Value;return new Iterator<object> () {int idx = -1;public Boolean hasnext () {return (idx + 1) < Array.getlength (Array);} Public Object Next () {Idx++;return array.get (Array, idx);} public void Remove () {throw new Unsupportedoperationexception ();}};} else {list<object> List = Arrays.aslist ((object[]) value); return List.iterator ();}} else if (value instanceof NodeList) {//lets iterate through DOM results after perforMing xpathsfinal NodeList NodeList = (NodeList) value;return new iterator<object> () {int idx = -1;public Boolean has Next () {return (idx + 1) < Nodelist.getlength ();} Public Object Next () {Idx++;return nodelist.item (idx);} public void Remove () {throw new Unsupportedoperationexception ();}};} else if (value instanceof string) {final String s = (String) value;//This code was optimized to only use a Scanner if need Ed, eg there is a delimiterif (delimiter! = null && s.contains (delimiter)) {//Use a scanner if it contains the de Limiterscanner scanner = new Scanner ((String) value), if (Default_delimiter.equals (DELIMITER)) {//We use the DEFAULT Delim Iter which is a comma and then cater for beans expressions with ognl//which could have balanced parentheses pairs as well.//if The value contains parentheses we need to balance those, to avoid iterating//in the middle of parentheses pair, so use T His regular expression (a bit hard to read)//The regexp would split by comma, but honor ParenTheses pair that may include commas//as well, eg if value = "Bean=foo?method=killer (A, B), Bean=bar?method=great (A, B)"//TH En the regexp would split that into two://, Bean=foo?method=killer (A, B)//-Bean=bar?method=great (A, B)//HTTP://ST Ackoverflow.com/questions/1516090/splitting-a-title-into-separate-partsdelimiter = ", (?! (?:[^\\(,]| [^\\)],[^\\)])+\\))";} Scanner.usedelimiter (delimiter); return Castutils.cast (scanner);} else {//Use a plain iterator this returns the value as is as there be only a single valuereturn new ITERATOR<OBJECT&G t; () {int idx = -1;public Boolean hasnext () {return idx + 1 = = 0 && (allowemptyvalues | | Objecthelper.isnotempty (s));} Public Object Next () {Idx++;return s;} public void Remove () {throw new Unsupportedoperationexception ();}};}} else {return collections.singletonlist (value). iterator ();}}
The method is defined in the Org.apache.camel.util.ObjectHelper class, with a large number of allowed types, but ultimately to a Java.uti.Iterator object, so that camel can traverse the individual element objects through the iterator, and then for each element object Create an Exchange object, and then set the element object to the body of the message, so that a message is decomposed for multiple copies.
Aggregation, which is just the inverse process of decomposition, is merging multiple messages based on route definition routes into a single message, such as:
The main problem for aggregation is how to determine what messages are to be aggregated and what the aggregation process is. To implement aggregation, you need to add aggregatedefinition to the route definition, Call the Processordefinition.aggregate method, which is primarily to provide an expression and Aggregationstrategy object that determines which messages need to be aggregated, which is used to determine how the specific aggregation process is performed.
A specific example of decomposition and aggregation is provided below, which implements an example function that decomposes a file on a per-line basis and is decomposed and then aggregated:
Package Com.xtayfjpk.camel;import Java.io.file;import Java.io.filenotfoundexception;import Java.util.Scanner; Import Org.apache.camel.camelcontext;import Org.apache.camel.exchange;import Org.apache.camel.processor;import Org.apache.camel.builder.routebuilder;import Org.apache.camel.impl.defaultcamelcontext;import Org.apache.camel.processor.aggregate.aggregationstrategy;import Org.apache.camel.support.ExpressionAdapter; public class Test {/** * @param args */public static void main (string[] args) throws Exception {Camelcontext Camelcontext = new Defaultcamelcontext (); Camelcontext.addroutes (new Routebuilder () {@Overridepublic void Configure () throws Exception {//poll the specified directory This.from ("File:h:/temp/in?noop=true")//Add splitdefinition, passing in a custom expression object. Split (new Expressionadapter () {@Overridepublic Object Evaluate (Exchange Exchange) {//Returns a class that implements the iterator interface. Each iteration of the element object creates a Exchangefile file = Exchange.getin (). GetBody (File.class); System.out.println (file); Scanner Scanner = null;if (file!=null) {try {sCanner = new Scanner (file),//Decomposition by line scanner.usedelimiter ("\ n");} catch (FileNotFoundException e) {e.printstacktrace ();}} return scanner;}}). Process (new Processor () {private int count = 0;public void process (Exchange Exchange) throws Exception {///sets the value of the associated key in the message, When the associated key value of the message is the same, the aggregation exchange.getin () is required. SetHeader ("Test_correlation_key", (++count)%2); System.out.println ("Body:" + exchange.getin (). GetBody ());}). Aggregate (Header ("Test_correlation_key"), new Aggregationstrategy () {Public Exchange aggregate (Exchange Oldexchange, Exchange newexchange) {//If Oldexchange is null, the description is the first decomposition package if (Oldexchange = = null) {return newexchange; } String Oldbody = Oldexchange.getin (). GetBody (String.class); System.out.println ("Old body:" + oldbody); String newbody = Newexchange.getin (). GetBody (String.class); SYSTEM.OUT.PRINTLN ("New body:" + newbody);//merge the new package with the old, and then set the message to the body of Oldexchange.getin (). Setbody (oldbody + "\ n") + newbody); Return oLdexchange;}}). Completiontimeout. Process (New Processor () {public void process (Exchange Exchange) throws Exception {//Sample post-processing, Perform output System.out.println ("Body:" + exchange.getin (). GetBody ());});}); Camelcontext.start (); Object object = new Object (); Synchronized (object) {object.wait ();}}}
In the process of decomposition and aggregation, some of the data associated with this will be set as properties of exchange, such as decomposition sequence number, decomposition completion, aggregation sequence, etc., details can be see the official Camel document:
Http://camel.apache.org/splitter.html
Http://camel.apache.org/aggregator.html
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Apache Camel decomposition and aggregation