3

I am trying to implement a Camel Component/Processor that takes one input and produces multiple output messages, similar to a Splitter. Like Splitter, the output should go to the next processor/endpoint in the route.

I have looked at Splitter & MulticastProcessor classes in the hope that I can reuse them or use similar logic. The idea, as I understood, is to create an new Exchange for each output and emit them. To do this, I need to provide the endpoint to which output is written to. This works, if I dynamically create the end point within the Processor class; my requirement is to send the output to the end point configured in the route. That is in the route below, mycomponent needs to write (multiple times) to file:output.

    <route>
        <from uri="file:input"/>
        <to uri="mycomponent:OrderFlow?multi.output=true"/>
        <to uri="file:output" />
    </route>

In case of Splitter, it is instantiated by SplitDefinition class which has access to the output Processor/Endpoint.

a) From within a Processor is it possible to access the configured Output Processor/Endpoint?

b) If not, should I be writing a ProcessorDefinition class for my processor? Any pointers on this would help.

Two solutions suggested below by Petter are,

a) Inject a Producer template b) Use Splitter component with a method call instead of writing a new component.

Krishnan
  • 91
  • 2
  • 4

1 Answers1

2

I assume you have read this page.

Yes, you can send multiple exchanges from a custom processor, but not really to the next processor in the flow. As in the link above, you can decouple the component implementation by injecting a producer template with a specific destination. You can cut your route into several parts using the direct or seda transport and make your component send the messages there. This way, you can reuse the code in several routes.

This is, as you point out, done in the splitter component (among others) in Camel core. Take a look at the multicastprocessor baseclass for example. However, there processors are aware of the following processors in the route, thanks to the route builder. You custom processor is not that lucky.

You can, non the less, extract that information from the CamelContext. Get hold of your route and there you can find the processors in the route. However, that seems like overcomplicating things.

UPDATE: Instead of trying to alter the DSL, make use of the already existing DSL and components.

.split().method("mycomponent", "OrderFlow")

Instead of emitting new exchanges, your OrderFlow method just needs to create a List<..> with the resulting messages.

Petter Nordlander
  • 22,053
  • 5
  • 50
  • 84
  • Thanks. I had looked at ProducerTemplate, but as I said, I am looking to send the output to next processor in the route similar to Splitter (want the route to be clean) – Krishnan Mar 02 '14 at 04:57
  • Are you implying that Splitter, which has access to the route definition, is privileged and other custom processors cannot access the same? There is not much documentation on these ProcessorDefinition classes - is it possible to write one for a custom processor, so that I can access the processor that consumes my output. Your solution of injecting producer template and splitting the route using direct transport makes lot of sense. Unfortunately my processor needs to as natural as Splitter, as it will be used by others to build route. – Krishnan Mar 02 '14 at 05:21
  • Yes, of course it perfectly possible to implement another "splitter-like" component. You will have to mess with the core of camel though (such as the ProcessorDefinition class among other things). I would advice against it. There are likely other ways to do what you wish to do. I'll update the answer with an example. – Petter Nordlander Mar 02 '14 at 21:29
  • Reusing Splitter instead of new component: We have considered that. We are trying to provide Camel wrapper for our transformation engine – Krishnan Mar 03 '14 at 03:11
  • We are trying to provide Camel wrapper for our transformation engine. Some of the complications are, a) Multiple outputs b) Very large outputs c) Producing output before the exchange completes. Some of these requirements rules out using a simple method call. All your suggestions have been extremely valuable to us. – Krishnan Mar 03 '14 at 03:23
  • Thanks for pointing out that it wouldn't be prudent to mess with ProcessorDefinition classes. If you have any other suggestions it would be of great help. – Krishnan Mar 03 '14 at 03:50