I am using rabbitmq, and can perform all the required functions like message routing according to bindings.
I have never used apache camel but have used rabbitmq.
My Question is what additional features with camel-rabbitmq provide that are not provided by rabbitmq alone.
Camel is an implementation of enterprise integration patterns whereas RabbitMQ is a messaging architecture.
Camel provides an abstraction so that endpoints are swappable with a minimum of fuss. If you were to use camel-rabitmq you could easily swap to jms for instance, or perhaps write to a file instead (or aswell).
You can also add routers, filters etc etc to your channels.
Related
I'm fairly new to Java and am currently writing a web application using a number of Dropwizard based micro services and Java8 SE. I now want to integrate a Message Queue for Async communication between the services and want to start by using a cloud based queue like Amazon SQS. However I don't want to lock myself into a particular cloud provider so would like the option of easily switching to another provider or using something like RabbitMQ or ActiveMQ later on. So my question is, is there a framework in Java that allows this? For example with Hibernate I can switch between databases with a simple config change, is there an equivalent for Message queues?
I've spent quite a bit of time researching this but haven't been able to find a definitive answer anywhere, so far I've found;
JMS, Which looks a bit like what I'm after but looks to only be available in the Java EE edition and may require and app server? Is that correct?
AMQP, Which looks like a low level protocol for message queue interoperability. There is also Apache Qpid Proton which looks like a pure AMQP message library but all the documentation and examples for Java seem to use the JMS.
All the tutorials I can find for specific MQs (Rabbit, etc) use those Queues specific client libraries.
Obviously I could add my own abstraction layer but don't want to re-invent the wheel and I suspect I'm not the first developer to want to do something like this.
Just as Hibernate or just JDBC for that matter allows you to switch amongst differing Database providers the JMS API allows you to switch amongst message Brokers or message Providers at will without breaking you code provided you are not using any specific vendor extensions in your code.
JMS is just an API, there is no JMS protocol only the API that various vendors implement and provide you a client to use with their messaging provider. You can use the JMS API from your Java 8 code just fine, you just need to pull in the JMS API jar using whatever build management tool you happen to have chosen along with the client jar from the vendor you happen to be using at that time. To see how to grab an Apache licensed version of the JMS API jar see the answer to this question.
From what I can see Amazon does offer a JMS implementation, the documentation here seems to cover it well.
When or if you decide to switch to another messaging product such as ActiveMQ or RabbitMQ there are JMS implementations offered by each that allow you to swap out the client and not need to change any existing code (again provided you aren't using any vendor extensions). If you switch to a messaging solutiuon that offers AMQP 1.0 support than there is a JMS over AMQP 1.0 implementation offered by the Apache Qpid project here.
I think you need to spend some time reading up on the JMS specification and some tutorials to get a handle on what JMS is and how leveraging JMS and JNDI you can create provider agnostic code.
JMS in the java world is one of the most common API for producing/consumming messages over queues. When using JMS you are free to use any JMS provider (activeMQ, rabbitMQ ...), and if do not make any direct call to your provider (only calling the JMS API) you can switch from one to another easily.
In order for the message to travel from a producer tu a consumer you need a broker ( a software that will handle them). Brokers can be hosted on a dedicated servers or embbeded in your application (I would not recommend the second option).
AMQP is a more recent protocol and is wire-level. Some Brokers are able to handle both AMQP and JMS.
Both AMQP and JMS can provide you with decent abstraction. However they both have their limits. On one hand with JMS you may be tempted to use some feature/fine configuration tuning, and then you may become implementation-depend due to a specific set of behaviors. On the other hand with AMPQ given the AMQP version you've choosen (0.9 or 1.0+), you only may be able to select only a few broker because those versions differs heavily and at the moment most broker only supports one of them.
Check your provider carefully if you're looking for JMS 2.0, some - i.e., ActiveMQ - only support JMS 1.1.
I have some doubts regarding Spring Integration :
Can we integrate more than two applications using Spring Integration framework?
Is it point to point intergration or middleware oriented integration?
In client-server architecture If both (client & server) are java based applications, then what should we use for synchronous communication ? means, should we go for Spring Integration or JAX-RPC ? Which one will be faster for synchronous communication ?
Spring Integration is a lightweight integration framework. It does not use or need a central broker (many see that as a benefit).
It is not just point to point; you can configure a many-to-many environment, but no broker is required. You can, of course, use a middleware broker if you wish (e.g. RabbitMQ or JMS).
There are many ways to perform synchronous (request/reply) integration. In Spring Integration, the components usually used for that are called gateways (outbound on the client, inbound on the server).
One of the benefits of this is the application doesn't have to know what technique is being used. With simple configuration changes, you can change the actual protocol used to whatever you want, with zero changes to the application itself.
Many techniques are provided out of the box, including ReST (http), SOAP WebServices, JMS, AMQP, TCP/IP, ...).
It's best not to think of synchronous integration as RPC - it's all about loose coupling using request/response messaging, with the message content being the contract, not the API.
One-way integration is achieved using channel-adapters rather than gateways.
I suggest you take a look at the reference documentation... http://static.springsource.org/spring-integration/reference/html/
This may be a very basic question. But I am bit confused.
I know RabbitMQ is a AMQP broker (meaning RabbitMQ implements / uses AMQP).
I used client libraries (jars) provided by RabbitMQ. Does it mean I used AMQP protocol which is used "internally" by RabbitMQ client APIs / libraries to connect to the RabbitMQ broker? Anything else I need to know about using AMQP?
Or is there a different route I need to follow to use AMQP?
How is a developer concerned about using AMQP other than just using the APIs of the any Message Broker like RabbitMQ, Apache QPid, etc?
I used client libraries (jars) provided by RabbitMQ. Does it mean I used AMQP protocol which is used "internally" by RabbitMQ client APIs / libraries to connect to the RabbitMQ broker?
Yes you have used AMQP protocol (probably); RabbitMQ isn't using internally AMQP. It uses AMQP to send messages from your application to RabbitMQ and from RabbitMQ to (your) other application; or viceversa.
Or is there a different route I need to follow to use AMQP?
Besides using the API you can use as an extension of Apache Camel or Spring Integration for example; it is more neat and you can use it in more parts of your application. Actually it doesn't matter how you using so long you respect the protocol.
How is a developer concerned about using AMQP other than just using the APIs of the any Message Broker like RabbitMQ, Apache QPid, etc?
AMQP is a protocol, just like HTTP; besides the API it defines the message format and has features as routing or queuing being served by the protocol rather by the application implementing the API.
I need to enhance the JMX interfaces of a distributed java application. The reason for choosing JMX is the simplicity of exposing data. These distributed apps exist in several different machines connected to a JMS server (activemq 5.7) (which in turn is connected to another JMS server to bridge 2 networks, also activemq 5.7).
What I would like to do, is to be able to access the remote JMX interfaces on the individual servers from anywhere on the JMS network. I would nee full JMX access as if accessing through the usual RMI interface. That means every type of action.
I understand I could use lingo to make the remote jmx interfaces talk to the JMS server, and from there my bridge should allow me access to them (assuming its configured correctly).
Is this a good approach? has anyone tried lingo for this purpose? Are there other options out there I may have not found?
A plan B could be to use apache camel RMI module, but it seems like if lingo is an option, it will be much more plug & play than this.
I think it's not a bad way to go. The one downside of using JMS that I can think of, off the top of my head, is the dependency on a broker, which most JMS implementations rely on.
On the other hand, it does present some interesting capabilities like discovery, asynchronous JMX invocation and pub/sub multicast style JMX operations where you could issue one operation request and receive back a response from all your MBeanServers.
I am not aware of any actual implementations, but it's probably not too difficult to implement. You simply need a configured client on each target JVM that will:
Listen for JMX requests: The listener will unmarshall the request (which should be an encoding of an MBeanServerConnection method invocation). Use a common topic for pub/sub style invocations, returning the marshalled result
to the destination specified in the JMSReplyTo property in the request message. Otherwise, you could allocate a queue per JVM, or pick a unique identifier for each JVM and use message selectors.
If you want to implement JMX notifications, you will need to implement a proxy NotificationListener that registers for the desired notifications and forwards them to the designated JMS destination on receipt.
You may also consider implementing a full blown javax.management.remote implementation which may integrate more smoothly into your environment by virtue of the standard adherence.
I have found the OpenDMK project very useful for extending/implementing JMX servers and clients. The library provides the basic building blocks for implementing a standard JMX remoting solution using a "custom" protocol. Basically, you implement a javax.management.remote.generic.MessageConnection which serves as the transport and invocation mechanism. All JMX invocations, responses and callbacks are serialized
into instances of javax.management.remote.message.Message, and they're all Serializable so you should not have any issues writing them into and reading them from JMS ObjectMessages.
A couple of additional benefits you will get from this approach are:
Provided you configiure the classpath correctly, you should be able to connect to your JVMs using any standard JMX tool such as JConsole.
The OpenDMK also provides the ability to federate MBeanServers which makes all your MBeanServer instances appear, and be accessible through one central MBeanServer. This feature requires a standard JMX remoting
implementation.
The OpenDMK also implements an interesting service discovery protocol, and it comes in a couple of different flavours including raw multicast and a "phone-home" approach which would mesh nicely with your JMS protocol.
I posted a mavenised project of the OpenDMK here if you're interested.
I am implementing a basic JMX client for java-agents using netty, and it optionally supports asynchronous JMX requests. Responses are delivered through a registered listener which is like a "reverse" MBeanServerConnection. In case this is useful, find the source here.
Jolokia (http://www.jolokia.org/) is also a great project for remote accessing JMX using REST and JSON. It does this automatic for you. And support batch operations as well.
I suggest to take a look at that.
If you use JMX to get AMQ statistics then it offers a plugin, so you can just using JMS messaging to get the stats instead of JMX: http://activemq.apache.org/statisticsplugin.html
I would use JMS to discover the URLs of the servers I am interested in and use plain JMX from then on. I don't see the advantage of sending every RMI call over JMS.
I currently work on a trading application that does not use camel.
It essentially takes in trades, does some processing and sends the details to an external system.
We now have a need to integrate with 3 new systems uusing FTP for 2 systems and JMS for 1 system.
I would like to use Camel in my application for these integrations. I have read a good chunk of camel in action but I was unclear on how we could kick off our camel routes
Essentially, we dont want to modify too drastically any part of the existing application as its working well in production.
In the existing application, we generate a Trade Value Object and its from this object that that I want to kick off our camel integration.
I dont have a database table or jms queue where I can kick off the route from.
I had a quick look at the Chapter on Bean routing and remoting in the Camel in Action book but I wanted to get peoples advise first before proceeding with any steps.
What would be the best approach for this integration?
Thanks
Damien
You can use Camel's POJO Producing feature that allows you to send a message to a camel endpoint from the java bean. If you have no need in JMS or DB you can use "direct:" or "seda:" or "vm:" endpoint as <from> part of your route.
Pojo producing as Konstantin V. Salikhov stated. However, you need to be sure you have a spring application and are scanning your beans with spring or wire them.
"If a bean is defined in Spring XML or scanned using the Spring component scanning mechanism and a is used or a CamelBeanPostProcessor then we process a number of Camel annotations to do various things such as injecting resources or producing, consuming or routing messages."
If this approach will add too much changes in your application, you could use a ProducerTemplate and just invoke a direct endpoint. (Or SEDA for that matter).
The choice of protocol here might be important. The direct protocol is a safe choice, since the overhead is simply a method call. Also, exceptions will propagate well through direct endpoints, as will transactions. As SEDA endpoints is asynchronous (like JMS) but does not feature persistence, there is a slight chance of loosing in flight data in case of a crash. This might or might not be an issue. However, with high load, the SEDA protocol stages better and give your application better resistance for load peaks.