Servicemix/Camel : how to leverage OSGI to create "pluggable" bundles? - apache-camel

Scenario : I'll try to put an analogy with the loan broker example from the EIP book
The customer sends a quote request
(The loan broker requests customer credit score from the credit bureau)
The loan broker sends quote requests to each bank.
The problem
In my case point 1 and 2 are in the same camel context (or osgi bundle)
Each bank has a separate bundle, exposing endpoints to the loan-broker-bundle through NMR
loan-broker-bundle doesn't know about the banks beforehand since we keep partnering with new banks every now and then
What I did
Created a registry class and a bankDescriptor interface in loan-broker-bundle
each bank bundle when started calls the registery to add its bankDescriptor (spring init) that tells the loan broker what endpoint to call to get a quote.
loan-broker-bundle main route uses recipientList (a processor sets target endpoints by asking the registery) to route quote requests
The question
Hoping my description was clear enough, you can see that this is a really simple implementation. What are its limits ? How can i turn this registery into an osgi service ?

I developed a solution like this based on SpringDM for a client. There's a full write up of how to do this at http://www.jakubkorab.net/2012/05/system-integrations-as-plugins-using-camel-and-servicemix.html with full source code available at https://github.com/FuseByExample/smx-application-plugins
Hope that helps.

In OSGi there is a great registry at your disposal: The OSGi service registry. So my proposal is to do this slightly differently. Define a service interface for the quote requests and store it in a api bundle. Then let each bank implement this interface and publish the implementation as an OSGi service.
The loan broker bundle can then list all OSGi services in the OSGi service registry and call each to get the quote. In blueprint there is a nice tag that you can use to inject the list into a bean property of List. Spring DM perhaps has something similar.
Camel currently does not have way to call all OSGi services of a type. We discussed a new osgi service compomnent that would be able to do this. So probably we will soon have a solution.

Related

How to access a remote web service by Camel CXF endpoint?

I was looking up online how to create a Camel's CXF producer (i.e. create a CXF endpoint that would produce a request to some local/remote web service). Generally, all the examples I could find would list the following steps:
First define the cxfEndpoint attributes:
<cxf:cxfEndpoint
id="orderEndpoint"
address="http://localhost:9000/order/"
serviceClass="camelinaction.order.OrderEndpoint"/>
Then send the request to that endpoint:
...to("cxf:bean:orderEndpoint");
Hmmm. I don't understand the concept. If this is a remote web service, all I usually have is the URL of the WSDL. I can get from it the address of the service... but I don't know what the serviceClass is and I don't have it on my classpath.
So how do I define that cxfEndpoint in case I only have the URL of the WSDL?
Or is there another type of endpoint I should use in that case?
I would suggest looking into WSDL first for cxf. Below are two links that I think should help you out quite a lot and has helped me in the past as well.
http://code.notsoclever.cc/camel-cxf-component-wsdl-first-example/
https://access.redhat.com/documentation/en-US/Fuse_ESB_Enterprise/7.0/html-single/Web_Services_and_Routing_with_Camel_CXF/index.html#ImplWs-WsdlFirst
On the Red Hat site you will need to start at chapter 3.
Hope this helps.

CXF Corba and Namingservice

I'm trying to build a service that also (beside of SOAP) uses CORBA/IIOP for communication. I followed the (CXF) CORBA Bank Demo and manged it to get it running. But despite of what is written in the README-File it needs no corba naming service.
What I need is, that the server registers it's service at a corba nameing service and the client looks up the server through the nameing service. Is there any way to achieve this goal ?
The bank demo uses a file to store the reference. The "corba/hello_world" sample uses a "corbaname" url in the wsdl to force the use of a naming service. Check that one or the "bank_ws_addressing" sample which also uses the corbaname urls.

A scalable bus with multiple Camel instances

My idea is to use camel to decouple modules. In order to support scalability and failover, I am wondering if the following architecture is adviced?
I have two applications with Camel embedded AppCamel1 and AppCamel2. Then I have standalone camel nodes Camel1 and Camel2.
AppCamel1 would have a route with fail-over/load balancing to Camel1 and Camel2. This way, if Camel1 crashes for example, Camel2 is used for failover.
Camel1 and 2 would do a REST call with the http component for example. Also there would be a request-reply from AppCamel1 up to camel1 or 2.
Is it a valid scenario?
What should I use to interconnect the different Camel instances (AppCamel1 to Camel1 or 2)? (I would like to know if it's possible to avoid another component like a jms server in the middle)
Thank you!
Edited following Boday's answer
the REST calls are from Camel1/2. I'd like to interconnect AppCamel1/2 to Camel1/2 and see if I can avoid anything in between. I guess mina is a possibility or even http but in that case a AppCamel1 and AppCamel2 need to know Camel1/2 which is not so good.
This is also being discussed at the Camel mailing list, where there is also some pointers and suggestions
http://camel.465427.n5.nabble.com/scalable-bus-with-multiple-Camel-instances-tp5606593p5606593.html
If you are trying to load balance HTTP requests to your AppCamel1/2, then you'd need a proxy server in between (apache mod_proxy, perlbal, etc). To load balance from AppCamel1/2 to Camel1/2, you can use Camel's load balancer or even JMS request/reply...
From AppCamel1/2 to Camel1/2, it sounds like you are using REST as the interface. If you need more complex communication between the instances, then I'd use JMS (via camel-activemq) for messaging and Hazelcast (via camel-hazelcast) for distributed caching/locking, etc.
If you use jms to communicate then you do not need a special load balancer. Just use one queue and let both Camel1/2 listen to the queue. Then they will automatically failover and load balance.
I would definetly go for a jms middleware. Activemq is the natural choice (camel is even considered a sub project of activemq). It is trivial to embedd amq along with your canel instances and cluster them. Activemq will then be able to handle both load balancing and failover for you.

Service Registry for Apache Camel Applications

A registry is a list of items with pointers for where to find the items, like the index on a database table or the card catalog for a library.
Correct me if I am wrong, from this definition, what I'd expect from a camel application registry is where a client application can (depending on the client protocol) do a lookup and based on metadata, selects a particular service and uses it as defined.
I am wondering if Apache Camel has anything close to this. Most of the service registries articles/implementations I have seen seems to address only SOAP protocols.
Regards.
You can use the REST API from camel-web to lookup routes and endpoint which is the "services" in Camel.
http://camel.apache.org/web-console.html
In terms of a SOA service registry then you may look at other products which specialize in that such as Apache ZooKepper
http://hadoop.apache.org/zookeeper/
You can use ManagementStrategy SPI to hook into events in Camel and track services as they are created/started/stopped etc. Then you can bridge that to your SOA service registry product of choice.
you can also use the CamelContext getEndpoints() and getEndpointsMap() APIs to browse the endpoints
see this post for some general monitoring information...
http://benoday.blogspot.com/2011/01/apache-camel-monitoring.html

Apache Camel: Keeping routing information completely independent of the Java Code

First of all thanks to folks who are currently involved in the development of Camel, I am grateful for all the hard work they have put in.
I am looking for some design advice.
The architecture is something like this:
I have a bunch of Java classes which when instantiated are required to connect to each other and send messages using Apache Camel. The design constraints require me to create a framework such that all routing information, producers, consumers, endpoints etc should be a part of the camel-context.xml.
An individual should have the capability to modify such a file and completely change the existing route without having the Java code available to him.(The Java code would not be provided, only the compiled Jar would be)
For example in One setup,
Bean A ->Bean B->Bean C->file->email.
in another
Bean B->Bean A->Bean C->ftp->file->email
We have tried various approached, but if the originating bean is not implemented as a Java DSL, the messages rate is very high because camel constantly invokes Bean A in the first example and Bean B in the second(they being the source).
Bean A and Bean B originate messages and are event driven. In case the required event occurs, the beans send out a notification message.
My transformations are very simple and I do not require the power of Java DSL at all.
To summarize, I have the following questions:
1) Considering the above constraints, I do I ensure all routing information, including destination addresses, everything is a part of the camel context file?
2) Are there example I can look at for keeping the routing information completely independent of the java code?
3) How do I ensure Camel does not constantly invoke the originating bean?
4) Does Camel constantly invoke just the originating bean or any bean it sends & messages to irrespective of the position of the bean in the entire messaging queue?
I have run out of options trying various ways to set this up. Any help would be appreciated.
Read about hiding the middleware on the Camel wiki pages. This allows you to let clients use an interface to send/receive messages but totally unaware of Camel (no Camel API used at all).
Even better consider buying the Camel in Action book and read chapter 14 which talks about this.
http://www.manning.com/ibsen/
Save 41% on Manning books: Camel in Action or ActiveMQ in Action. Use code s2941. Expires 6th oct. http://www.manning.com/ibsen/
If you consider using ServiceMix of FuseESB, you might want to separate your routes in two parts.
First part would be the Event-driver bean that trigger the route. It could push messages to the ServiceNMR (see http://camel.apache.org/nmr.html).
The other part would be left to the framework users, using Spring DSL. It would just listen to message on the NMR (push by the other route) and do whatever they want with it.
Of course endpoint definition could be propertized using servicemix configuration service (see http://camel.apache.org/properties.html#Properties-UsingBlueprintpropertyplaceholderwithCamelroutes)

Resources