Camel Splitter: Add individual headers based on body

apache camel split xml example
camel share unit of work
apache camel parallel processing

I am trying to split a message containing a map. According to my tutorial, I have to use a custom service to implement the actual splitting

public class CustomService {
  public List split(Map map) {
    return map.values();
  }
}

//route ...
.split().method(CustomService.class, "split")
   .choice()
   //...
.end()

So far, everything works fine. However, now I want to route the messages differently depending on some header value I would like to set in the split(Map) message. Is it possible to add different header values for each message during the split?

You can only add headers in the split method if you return a List<Message> eg org.apache.camel.Message instances where you can adjust the headers.

Something a long the lines of (mind pseudo like code)

public class CustomService {
  public List split(Exchange exchange) {
    List list = new ArrayList();

    Map map = exchange.getIn().getBody(Map.class);
    for (Object value : map.values()) {
       // either copy or create a new DefaultMessage
       Message msg = new DefaultMessage();
       msg.setBody(value);
       // we want to copy the existing headers
       msg.setHeaders(exchange.getIn().getHeaders();
       // and then customize the headers
       msg.setHeader("foo", "bar");
       list.add(msg);
    }
    return list;
  }
}

org.apache.camel.Message.setHeaders java code examples, Camel Splitter: Add individual headers based on body. public class CustomService { public List split(Exchange exchange) { List list = new ArrayList(); Map map  This reduces memory usage as the splitter do not split all the messages first, but then we do not know the total size, and therefore the org.apache.camel.Exchange#SPLIT_SIZE is empty. In non-streaming mode (default) the splitter will split each message first, to know the total size, and then process each message one by one.

@Claus, thanks- your solution (almost) worked. Only change was instead of

msg.setHeaders(exchange.getIn().getHeaders();

I had

msg.setHeaders(new HashMap<String, Object> (exchange.getIn().getHeaders()));

This way each message has its own header.

Split, Splits a single message into many sub-messages. This header is also set in stream based splitting, but only on the completed Exchange. You can use the tokenizer expression in the Spring DSL to split bodies or headers using a token. String[] parts = body.split(","); for (String part : parts) { answer.add(part); } return​  What the Splitter returns. Camel 2.2 or older: The Splitter will by default return the last splitted message. Camel 2.3 and newer The Splitter will by default return the original input message. For all versions You can override this by suppling your own strategy as an AggregationStrategy. There is a sample on this page (Split aggregate request

I would suggest another solution because if you split and add camel headers in one method it's not that obvious for others that this happens in the same method. Instead I would suggest, that you "convert" your map into custom POJO's which contain all information you need for splitting and routing.

So each entry in your map becomes an own custom POJO which you can collect in a list which is then splittable.

Here is an example of what I did in the (almost) same situation:

.log(INFO, log, "Some information in my route")
.process(mapToPOJOConverter) // An custom processor which does nothing more than converting the Map to your java.util.List of POJO's. Can also be a custom TypeConverter
.split(simple("${body}")).shareUnitOfWork().stopOnException() //Split the List so that in your splitted route you'll get each custom POJO
.to("direct:internAfterSplit")

from("direct:internAfterSplit").routeId(ROUTE_ALIAS_KUNDENARBEITSLISTE_INTERN) //Always use routeId for easy identifying where problems might be
  .log(INFO, log, "Start Route: ${routeId}")
  .bean(yourExchangeEnricher, "setHeadersIntoExchange")
  .log(INFO, log, "Message is rooted to: [your custom endpoint]")
  .to("[your custom endpoint which depends on the headers]")

With this way it's always obvious in the route where the headers are generated which are then used in the endpoint. I personally try to avoid java.util.Map when I implement Camel routes, as most times there is a better solution instead of java.util.Map like an own POJO.

Splitter, From Camel 2.9 onwards this header is also set in stream based splitting, but only on You can use the tokenizer expression in the Spring DSL to split bodies or headers of the message // with a certain header value .split().method("​mySplitterBean", String[] parts = body.split(","); for (String part : parts) { answer.​add(part); }  Teams. Q&A for Work. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information.

8.4. Splitter Red Hat JBoss Fuse 6.2, The Apache Camel splitter actually supports two patterns, as follows: from an incoming message and insert them into separate outgoing messages: the tokenize expression in the XML DSL to split bodies or headers using a token, where the as Apache Camel have out // of the box support for splitting a String based on  Available as of Camel 2.8. See details at Multicast. Sharing unit of work. Available as of Camel 2.8. The Splitter will by default not share unit of work between the parent exchange and each splitted exchange. This means each sub exchange has its own individual unit of work. For example you may have an use case, where you want to split a big

How to Implement the Splitter and Aggregator Patterns with Apache , I have found that Apache Camel is a good way to load data from log files into a database. Read on to see how I did this using the splitter and aggregator pat the inversion of control so the developer can switch between different if (​oldExchange == null) { list = new ArrayList(); list.add(newBody); newIn. If set to true, the body of the mail message is mapped to the body of the Camel IN message, the mail headers are mapped to IN headers, and the attachments to Camel IN attachment message. If this option is set to false then the IN message contains a raw javax.mail.Message.

java - Camel Splitter: Add individual headers based on body -, java - Camel Splitter: Add individual headers based on body -. i trying split message containing map. according tutorial, have utilize custom service implement  This example uses the following frameworks: Maven 3.2.3; Apache Camel 2.15.1; Spring 4.1.5.RELEASE; Eclipse as the IDE, version Luna 4.4.1.; Dependencies. We are just relying camel’s core components, the spring based components and the logger component in case you want to log something so our pom.xml consists of:

Comments
  • But, doesn't this lead to messages contain messages as payload? So the outer message does not contain the header values, so I can't use that for routing messages.
  • No if its an org.apache.camel.Message then its used as-is
  • @Claus Ibsen msg.setHeader("foo", mapKey ); results the same "foo" header for each msg...