0

New Camel user here.

I have a Spring Boot / Camel app and successfully got a route working which polls a REST endpoint, splits the JSON array into custom POJOS, transforms each one into one of our Protobufs, and then writes the protobuf out to our RabbitMQ.

So far so good.

However, it took me quite a bit of work to debug and get that last step working (writing out to the bus). Basically, I could never establish a connection to the bus using ConnectionFactory and instead, eventually figured out how to do it by putting the entire connection/writing to the bus using just the .to() statement in the DSL.

So I'm really, really interested to know what I was doing wrong with ConnectionFactory. Any help would be much appreciated!

Ok, so this is what worked:

(newlines added for clarity)

.to(“rabbitmq://hostname:5672/exchange?
    username=user&
    password=password&
    vhost=sandbox&
    exchangeType=topic&
    routingKey=routingkey&
    durable=false&
    autoDelete=false”);

Actually, I have a quick question here: Is doing the above wasteful in the sense that the connection isn't pooled and it's establishing the connection with every single write?

Ok, and this is what didn't work and kept giving me a java.net.ConnectException: Connection refused error:

RabbitMQEndpoint endpoint = new RabbitMQEndpoint();

endpoint.setHostname(“hostname”);
endpoint.setVhost(“sandbox”);
endpoint.setUsername(“user”);
endpoint.setPassword(“password”);
endpoint.setPortNumber(5672);
endpoint.setRoutingKey(“routingkey”);
endpoint.setExchangeName(“exchange”);

endpoint.setExchangeType(“topic”);
endpoint.setDurable(false);
endpoint.setAutoDelete(false);

Connection connectionFactory = new RabbitMQConnectionFactorySupport().createFactoryFor(endpoint);

So what am I missing??

For what it's worth, if the above connection worked, I was going to write the bus with the following .to() statement. Does it look correct? In particular, can I specify anything after the 'rabbitmq:' in place of the 'bogusbus'?

.to(“rabbitmq:bogusbus?exchangeType=topic&exchangeName=exchange&routingKey=routingkey”);

Thank you so much for your help!

Ron C.
  • 15
  • 3

1 Answers1

0

According to the documentation you can configure a com.rabbitmq.client.ConnectionFactory and then reference it as follows in your route:

.to("rabbitmq:exchangeName?connectionFactory=#rabbitConnectionFactory&...")

Where rabbitConnectionFactory is the bean name of the connection factory instance in your bean registry (notice the needed #).

Take care that all connection options on the URI are ignored if you reference a connectionFactory!

burki
  • 6,741
  • 1
  • 15
  • 31
  • Thank you for that. Now I remember reading about that syntax. Would you happen to have any suggestions about why I can't get the ConnectionFactory to connect? i.e. I'm failing long before I even get to the route. As I wrote about, my RabbitMQ is good, and I can connect to it and write when I do everything in the .to() in the route. But when I try to establish a ConnectionFactory outside the route, I'm apparently missing some "secret sauce" when setting up my endpoint... Thanks again. – Ron C. Jun 27 '18 at 17:29
  • If you want to use it with Camel you don't need the `RabbitMQEndpoint` at all, just the `ConnectionFactory`. Or do you want to use it without Camel? Then I would recommend using [spring-amqp](http://spring.io/projects/spring-amqp) where you get the typical template abstraction of spring – burki Jun 28 '18 at 07:25
  • Thanks again. I am using Rabbit with Camel. Using the `RabbitMQEndpoint` seemed to be needed because there were a few values I couldn't set using just the ConnectionFactory. Specifically, there were no setters for `exchangeType`, `durable` and `autoDelete`. I know I can specify them as part of the big URI in the `.to()`, but I thought it would be cleaner to get everything in the ConnectionFactory, and then have as short a URI as possible in the `.to()`. – Ron C. Jun 28 '18 at 15:01
  • On another note, the `new RabbitMQConnectionFactorySupport().createFactoryFor(endpoint)` is no longer failing. However the `.to()` fails because I can't get my `rabbitConnectionFactory` properly registered as a Bean. I am using the `#` in the URI. FWIW, I was setting up the ConnectionFactory inside the RouteBuilder configure(). I tried making `rabbitConnectionFactory` a class var, and created an annotated getter (in the same RouterBuilder class) to return it so the URI could use it ... but it didn't work. I think I'll stop wasting time and just use the big URI... – Ron C. Jun 28 '18 at 15:10
  • Since we are using Spring Framework it is simply the Spring bean name that is used in properties like `connectionFactory=#rabbitConnectionFactory`. Camel also supports [other registries](http://camel.apache.org/registry.html) but I don't know how to use it. – burki Jun 28 '18 at 15:22
  • Well, I did some more refactoring and pulled out all the ConnectionFactory stuff into its own `RabbitConnectionFactory` class annotated with `Bean` -- and now things are starting to work (although now I can't use `{{property}}` ... sigh). However, `exchangeType`, `durable` and `autoDelete` still need to be specified in the URI, as setting them on the `RabbitMQEndpoint` object seems to do nothing. So now the `.to()` in my route looks like: `.to("rabbitmq{{rabbitmq.exch}}?connectionFactory=#myRabbitConnectionFactory&exchangeType=topic&durable=false&autoDelete=false")` – Ron C. Jun 28 '18 at 15:57