How to send a message using Apache Camel? - java

I am trying to create a sample application hosted at "mina:tcp://localhost:9991" that sends a very simple message to a server hosted at "mina:tcp://localhost:9990".
Now admittedly I have some problems understanding how to do this. My first approach was to create a class called Message, that has two fields: String order and String host. However, I am terribly confused on how to do this.
First I tried to follow the loadbalancer-example basing myself on the ReportGenerator and create a MessageGenerator class that could create a message and return it:
http://camel.apache.org/loadbalancing-mina-example.html
However, there is a problem, I need parameters to create my Message, something that doesn't happen when creating the Report from the example:
//Message constructor
public Message(String order, String host){
//constructor stuff
}
By reading Camel in Action I know how to use beans to call methods that have no parameters, however I still do not understand how I should use them to call a method that has several parameters (Am I forced to use processors?)
Then i realized that perhaps I am complicating things a little bit and there is an easier way to send messages. So I tried another approach that resulted in a small sample of code that does not work as well. I have created a separate question for that matter:
Apache camel send a simple message
Obviously I am doing something wrong and I don't get what. So, I have 2 questions:
Manning's Camel in Action defines an Easy way and a Hard way to use beans, but I did not understand the easy way of using beans with parameters. Can someone provide an example of it?
Is there a way to send a message composed of several fields in Camel (an easy way, without processors) that does not involve using beans? If so, how?

There are several ways to sends Messages in Camel. According to the help provided in the Camel forums, the two best are:
Using beans linked to POJOS and routes (example: http://camel.apache.org/loadbalancing-mina-example.html)
Using the Producer Template (docs: http://camel.apache.org/producertemplate.html)
Hope it helps someone one day.

Related

Execute a camel route directly

I recently took over some Java code and there was a method that took in an object and based on some properties of that object, performed some processing on that object.
I was playing around with Apache Camel and was able to define a route that accomplished the same task. Where I am struggling is, how can I find the easiest way to pass an object to the route and execute the logic? What I have right now is a
producerTemplate.sendBody("direct:blah", myObject)
and the route itself defines a
from("direct:blah").process(...)
The above is working fine, albeit a little slower than before.
Is this the simplest way to replace the logic of a method? I was hoping to just be able to grab the route itself and pass an object to it for execution, but I don't see any ways to do this.
You don't necessarily need a from().process(). You can also inject an endpoint to your method. For example:
#Consume(uri = "direct:blah")
public void onFileSendToQueue(String body, #Header("CamelFileName") String name) {
LOG.info("Incoming file: {}", name);
producer.sendBody(body);
}
You can do the same for producers as well. See the Camel pojo messaging for more details.
http://camel.apache.org/pojo-messaging-example.html

Producing multiple outputs from a Camel Processor/Component

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.
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.

Message driven bean and database

I followed the following tutorial of Netbeans on creating the Enterprise Application using the IDE. I just wanted to know why the usage of Message driven bean is preferred here for the save or persist method? And why not for the other database operations such as findAll?
https://netbeans.org/kb/docs/javaee/maven-entapp.html
Message Driven Beans are asynchronous components, to illustrate the concept, asynchronous communication works pretty much like email communication, you send the email and that's it, you can only hope for the best, and expect that the recipient processes your mail as soon as possible and reply back if necessary (in a different communication), on the other hand, synchronous communication works pretty much like a phone call, you get your response during the same communication, without the need to start a new one.
In your case, when a client invokes findAll he's quite likely expecting to get a list of results in the same communication (synchronously: 'server, give me right now all the customers in the system'), in which case an MDB (asynchronous) is simply useless, on the other hand, when a client invokes save he might not want to wait for an answer (asynchronously: 'server, just try to save this info, i don't need to know right now if you succeeded or not').
There's a lot more info here.

How to build pipes-and-filters eip pattern with apache-camel

I'm trying to do a PoC in order to implement the pipes and filters eip pattern with Apache Camel.
From Camel documentation, I'm assuming that each filter must be implemented as an Endpoint ("With Camel you can split your processing across multiple independent Endpoint instances which can then be chained together.")
So, if I understood correctly, the Authenticate filter (from the example) must implement the Endpoint interface.
The "problem" is that I don't want to "re-invent the wheel". So instead of implementing the interface from the scratch, I'm almost sure that I can use an already implemented one. And the one is the BeanEndpoint.
Is that right?
I found a few examples of pipes and filters patterns (like this one) but none of then show how to implement the beans.
Can someone provide a bean implementation example?
TIA,
Bob
First of all, although I get where you're coming from when you say "camel implements filters as endpoints", I wouldn't strictly classify them as endpoints. More like message transformer/translators in my opinion.
So, in case you need to implement a custom filter as per your requirement, use the processor interface.
Basically, write a class(say, CustomProcessor) that implements Camel's Processor and write your custom filter strategy. Then, call it in your route as to("CustomProcessor").
The Processor page will surely clear all your concerns, so please have a look.
Also I assume you're aware of the camel message-filter pattern.
Thank you.
The Camel EIPs is listed here, and they all have examples and whatnot
http://camel.apache.org/eip
So for the pipes and filters you can find it on that link and see some examples
http://camel.apache.org/pipes-and-filters.html
And it seems you are new to Camel. Then I suggest to read this intro article to get your heads around Camel: http://java.dzone.com/articles/open-source-integration-apache

How am I supposed to use Apache XML-RPC's TypeConvertorFactory on the server side?

I am struggling to get Apache XML-RPC to call my TypeConvertorFactory at all. It is calling it on the client side (only return values confirmed to work so far, haven't tested parameters) but the server side isn't calling it at all.
My initialisation code looks like this:
XmlRpcServlet servlet = new XmlRpcServlet();
XmlRpcServerConfigImpl config = new XmlRpcServerConfigImpl();
config.setEnabledForExtensions(true);
servlet.getXmlRpcServletServer().setConfig(config);
servlet.getXmlRpcServletServer().setTypeConverterFactory(
new ServerTypeConvertorFactory());
The API looks like this:
private interface API {
AvailableLicencesResponse availableLicences();
}
AvailableLicencesResponse is just an ordinary boring, albeit deeply nested JavaBean.
At the moment, the server sends this response as Base64 (this works because I called setEnabledForExtensions(true) - but if I don't call that, I get "unexpected end of stream" type errors instead, with no additional error anywhere to tell me why.)
I have set breakpoints inside ServerTypeConvertorFactory and it seems that none of the methods are being called on the server. The same breakpoints show the client calling convert() when the server hands back the result, but the result is already the correct type due to serialisation magic so I don't need to convert it.
Essentially, what I am trying to do is to implement a wire protocol which conforms to standard XML-RPC (and doesn't use huge amounts of Base64 data...) while still having an API which doesn't require a thousand casts and calls to Map.get(). I also want to avoid having to make more calls than necessary, which is why I'm returning a bean instead of having separate methods to get each property of it, which would have worked too.
(Also, if there is a simpler to use API than this one, I'm open for suggestions. It started out being really easy, but that's until you need to customise it. Also, anyone suggesting Axis or other SOAP-based APIs will be shot at dawn.)

Categories

Resources