You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2018/03/08 10:45:51 UTC
[camel] 05/05: CAMEL-12330: Allow to configure more option on
rabbitmq component level.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
commit fd11cddb05e53719e3512fc3833901f7c918c406
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 8 11:07:36 2018 +0100
CAMEL-12330: Allow to configure more option on rabbitmq component level.
---
.../src/main/docs/rabbitmq-component.adoc | 54 ++++++++++++++++------
.../component/rabbitmq/RabbitMQComponent.java | 48 ++++++++++++++++++-
.../camel/component/rabbitmq/RabbitMQEndpoint.java | 4 +-
.../component/rabbitmq/RabbitMQComponentTest.java | 4 +-
.../RabbitMQLookupConnectionFactoryTest.java | 44 ++++++++++++++++++
.../java/sample/camel/SampleCamelApplication.java | 13 ++++++
.../src/main/resources/application.properties | 3 +-
.../springboot/RabbitMQComponentConfiguration.java | 33 +++++++++++++
8 files changed, 183 insertions(+), 20 deletions(-)
diff --git a/components/camel-rabbitmq/src/main/docs/rabbitmq-component.adoc b/components/camel-rabbitmq/src/main/docs/rabbitmq-component.adoc
index 35f1e2f..30eca55 100644
--- a/components/camel-rabbitmq/src/main/docs/rabbitmq-component.adoc
+++ b/components/camel-rabbitmq/src/main/docs/rabbitmq-component.adoc
@@ -23,11 +23,21 @@ for this component:
=== URI format
+The old syntax is *deprecated*:
[source,text]
----
rabbitmq://hostname[:port]/exchangeName?[options]
----
+Instead the hostname and port is configured on the component level, or
+can be provided as uri query parameters instead.
+
+The new syntax is:
+[source,text]
+----
+rabbitmq:exchangeName?[options]
+----
+
Where *hostname* is the hostname of the running rabbitmq instance or
cluster. Port is optional and if not specified then defaults to the
RabbitMQ client default (5672). The exchange name determines which
@@ -37,7 +47,7 @@ exchange name determines which exchange the queue will bind to.
=== Options
// component options: START
-The RabbitMQ component supports 5 options which are listed below.
+The RabbitMQ component supports 7 options which are listed below.
@@ -48,6 +58,8 @@ The RabbitMQ component supports 5 options which are listed below.
| *portNumber* (common) | Port number for the host with the running rabbitmq instance or cluster. | 5672 | int
| *username* (security) | Username in case of authenticated access | guest | String
| *password* (security) | Password for authenticated access | guest | String
+| *connectionFactory* (common) | To use a custom RabbitMQ connection factory. When this option is set, all connection options (connectionTimeout, requestedChannelMax...) set on URI are not used | | ConnectionFactory
+| *autoDetectConnection Factory* (common) | Whether to auto-detect looking up RabbitMQ connection factory from the registry. When enabled and a single instance of the connection factory is found then it will be used. An explicit connection factory can be configured on the component or endpoint level which takes precedence. | true | boolean
| *resolveProperty Placeholders* (advanced) | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | boolean
|===
// component options: END
@@ -79,6 +91,7 @@ with the following path and query parameters:
|===
| Name | Description | Default | Type
| *autoDelete* (common) | If it is true, the exchange will be deleted when it is no longer in use | true | boolean
+| *connectionFactory* (common) | To use a custom RabbitMQ connection factory. When this option is set, all connection options (connectionTimeout, requestedChannelMax...) set on URI are not used | | ConnectionFactory
| *connectionTimeout* (common) | Connection timeout | 60000 | int
| *deadLetterExchange* (common) | The name of the dead letter exchange | | String
| *deadLetterExchangeType* (common) | The type of the dead letter exchange | direct | String
@@ -120,7 +133,6 @@ with the following path and query parameters:
| *automaticRecoveryEnabled* (advanced) | Enables connection automatic recovery (uses connection implementation that performs automatic recovery when connection shutdown is not initiated by the application) | | Boolean
| *bindingArgs* (advanced) | *Deprecated* Key/value args for configuring the queue binding parameters when declare=true | | Map
| *clientProperties* (advanced) | Connection client properties (client info used in negotiating with the server) | | Map
-| *connectionFactory* (advanced) | To use a custom RabbitMQ connection factory. When this option is set, all connection options (connectionTimeout, requestedChannelMax...) set on URI are not used | | ConnectionFactory
| *exchangeArgs* (advanced) | *Deprecated* Key/value args for configuring the exchange parameters when declare=true | | Map
| *exchangeArgsConfigurer* (advanced) | *Deprecated* Set the configurer for setting the exchange args in Channel.exchangeDeclare | | ArgsConfigurer
| *networkRecoveryInterval* (advanced) | Network recovery interval in milliseconds (interval used when recovering from network failure) | 5000 | Integer
@@ -164,7 +176,19 @@ And then refer to the connection factory in the endpoint uri as shown below:
<camelContext>
<route>
<from uri="direct:rabbitMQEx2"/>
- <to uri="rabbitmq://localhost:5672/ex2?connectionFactory=#rabbitConnectionFactory"/>
+ <to uri="rabbitmq:ex2?connectionFactory=#rabbitConnectionFactory"/>
+ </route>
+</camelContext>
+----
+
+From Camel 2.21 onwards the `ConnectionFactory` is auto-detected by default, so you can just do
+
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:rabbitMQEx2"/>
+ <to uri="rabbitmq:ex2"/>
</route>
</camelContext>
----
@@ -255,7 +279,7 @@ routing key B,
[source,java]
----
-from("rabbitmq://localhost/A?routingKey=B")
+from("rabbitmq:A?routingKey=B")
----
To receive messages from a queue with a single thread with auto
@@ -263,21 +287,21 @@ acknowledge disabled.
[source,java]
----
-from("rabbitmq://localhost/A?routingKey=B&threadPoolSize=1&autoAck=false")
+from("rabbitmq:A?routingKey=B&threadPoolSize=1&autoAck=false")
----
To send messages to an exchange called C
[source,java]
----
-to("rabbitmq://localhost/C")
+to("rabbitmq:C")
----
Declaring a headers exchange and queue
[source,java]
----
-from("rabbitmq://localhost/ex?exchangeType=headers&queue=q&bindingArgs=#bindArgs")
+from("rabbitmq:ex?exchangeType=headers&queue=q&bindingArgs=#bindArgs")
----
and place corresponding `Map<String, Object>` with the id of "bindArgs" in the Registry.
@@ -299,8 +323,8 @@ in the example below with foo -> bar:
[source,java]
----
-from("rabbitmq://localhost/foo")
- .to("rabbitmq://localhost/bar")
+from("rabbitmq:foo")
+ .to("rabbitmq:bar")
----
Then beware that Camel will route the message to itself, eg foo -> foo. So why is that?
@@ -315,17 +339,17 @@ To avoid this you need to either:
[source,java]
----
-from("rabbitmq://localhost/foo")
+from("rabbitmq:foo")
.removeHeader("rabbitmq.EXCHANGE_NAME")
- .to("rabbitmq://localhost/bar")
+ .to("rabbitmq:bar")
----
- Or turn on `bridgeEndpoint` mode on the producer:
[source,java]
----
-from("rabbitmq://localhost/foo")
- .to("rabbitmq://localhost/bar?bridgeEndpoint=true")
+from("rabbitmq:foo")
+ .to("rabbitmq:bar?bridgeEndpoint=true")
----
From Camel 2.21 onwards this has been improved so you can easily route between exchanges.
@@ -335,8 +359,8 @@ For example to send to cheese exchange you can do
[source,java]
----
-from("rabbitmq://localhost/foo")
+from("rabbitmq:foo")
.setHeader("rabbitmq.EXCHANGE_OVERRIDE_NAME", constant("cheese"))
- .to("rabbitmq://localhost/bar")
+ .to("rabbitmq:bar")
----
diff --git a/components/camel-rabbitmq/src/main/java/org/apache/camel/component/rabbitmq/RabbitMQComponent.java b/components/camel-rabbitmq/src/main/java/org/apache/camel/component/rabbitmq/RabbitMQComponent.java
index 39515a3..d17fef4 100644
--- a/components/camel-rabbitmq/src/main/java/org/apache/camel/component/rabbitmq/RabbitMQComponent.java
+++ b/components/camel-rabbitmq/src/main/java/org/apache/camel/component/rabbitmq/RabbitMQComponent.java
@@ -18,7 +18,9 @@ package org.apache.camel.component.rabbitmq;
import java.net.URI;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import javax.net.ssl.TrustManager;
import com.rabbitmq.client.ConnectionFactory;
@@ -46,6 +48,10 @@ public class RabbitMQComponent extends UriEndpointComponent {
private String username = ConnectionFactory.DEFAULT_USER;
@Metadata(label = "security", defaultValue = ConnectionFactory.DEFAULT_PASS, secret = true)
private String password = ConnectionFactory.DEFAULT_PASS;
+ @Metadata(label = "common")
+ private ConnectionFactory connectionFactory;
+ @Metadata(label = "common", defaultValue = "true")
+ private boolean autoDetectConnectionFactory = true;
public RabbitMQComponent() {
super(RabbitMQEndpoint.class);
@@ -81,7 +87,22 @@ public class RabbitMQComponent extends UriEndpointComponent {
}
// ConnectionFactory reference
- ConnectionFactory connectionFactory = resolveAndRemoveReferenceParameter(params, "connectionFactory", ConnectionFactory.class);
+ ConnectionFactory connectionFactory = resolveAndRemoveReferenceParameter(params, "connectionFactory", ConnectionFactory.class, getConnectionFactory());
+
+ // try to lookup if there is a single instance in the registry of the ConnectionFactory
+ if (connectionFactory == null && isAutoDetectConnectionFactory()) {
+ Map<String, ConnectionFactory> map = getCamelContext().getRegistry().findByTypeWithName(ConnectionFactory.class);
+ if (map != null && map.size() == 1) {
+ Map.Entry<String, ConnectionFactory> entry = map.entrySet().iterator().next();
+ connectionFactory = entry.getValue();
+ String name = entry.getKey();
+ if (name == null) {
+ name = "anonymous";
+ }
+ LOG.info("Auto-detected single instance: {} of type ConnectionFactory in Registry to be used as ConnectionFactory when creating endpoint: {}", name, uri);
+ }
+ }
+
@SuppressWarnings("unchecked")
Map<String, Object> clientProperties = resolveAndRemoveReferenceParameter(params, "clientProperties", Map.class);
TrustManager trustManager = resolveAndRemoveReferenceParameter(params, "trustManager", TrustManager.class);
@@ -163,4 +184,29 @@ public class RabbitMQComponent extends UriEndpointComponent {
this.password = password;
}
+ public ConnectionFactory getConnectionFactory() {
+ return connectionFactory;
+ }
+
+ /**
+ * To use a custom RabbitMQ connection factory. When this option is set, all
+ * connection options (connectionTimeout, requestedChannelMax...) set on URI
+ * are not used
+ */
+ public void setConnectionFactory(ConnectionFactory connectionFactory) {
+ this.connectionFactory = connectionFactory;
+ }
+
+ public boolean isAutoDetectConnectionFactory() {
+ return autoDetectConnectionFactory;
+ }
+
+ /**
+ * Whether to auto-detect looking up RabbitMQ connection factory from the registry.
+ * When enabled and a single instance of the connection factory is found then it will be used.
+ * An explicit connection factory can be configured on the component or endpoint level which takes precedence.
+ */
+ public void setAutoDetectConnectionFactory(boolean autoDetectConnectionFactory) {
+ this.autoDetectConnectionFactory = autoDetectConnectionFactory;
+ }
}
diff --git a/components/camel-rabbitmq/src/main/java/org/apache/camel/component/rabbitmq/RabbitMQEndpoint.java b/components/camel-rabbitmq/src/main/java/org/apache/camel/component/rabbitmq/RabbitMQEndpoint.java
index 1342a98..480fe73 100644
--- a/components/camel-rabbitmq/src/main/java/org/apache/camel/component/rabbitmq/RabbitMQEndpoint.java
+++ b/components/camel-rabbitmq/src/main/java/org/apache/camel/component/rabbitmq/RabbitMQEndpoint.java
@@ -66,6 +66,8 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
private String password = ConnectionFactory.DEFAULT_PASS;
@UriParam(defaultValue = ConnectionFactory.DEFAULT_VHOST)
private String vhost = ConnectionFactory.DEFAULT_VHOST;
+ @UriParam(label = "common")
+ private ConnectionFactory connectionFactory;
@UriParam(label = "consumer,advanced", defaultValue = "10")
private int threadPoolSize = 10;
@UriParam(label = "consumer", defaultValue = "true")
@@ -109,8 +111,6 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
@UriParam(label = "advanced")
private Map<String, Object> clientProperties;
@UriParam(label = "advanced")
- private ConnectionFactory connectionFactory;
- @UriParam(label = "advanced")
private Boolean automaticRecoveryEnabled;
@UriParam(label = "advanced", defaultValue = "5000")
private Integer networkRecoveryInterval = 5000;
diff --git a/components/camel-rabbitmq/src/test/java/org/apache/camel/component/rabbitmq/RabbitMQComponentTest.java b/components/camel-rabbitmq/src/test/java/org/apache/camel/component/rabbitmq/RabbitMQComponentTest.java
index 5506aab..15de74b 100644
--- a/components/camel-rabbitmq/src/test/java/org/apache/camel/component/rabbitmq/RabbitMQComponentTest.java
+++ b/components/camel-rabbitmq/src/test/java/org/apache/camel/component/rabbitmq/RabbitMQComponentTest.java
@@ -92,7 +92,9 @@ public class RabbitMQComponentTest {
String uri = "rabbitmq:special.host:14/queuey";
String remaining = "special.host:14/queuey";
- return new RabbitMQComponent(context).createEndpoint(uri, remaining, params);
+ RabbitMQComponent comp = new RabbitMQComponent(context);
+ comp.setAutoDetectConnectionFactory(false);
+ return comp.createEndpoint(uri, remaining, params);
}
@Test
diff --git a/components/camel-rabbitmq/src/test/java/org/apache/camel/component/rabbitmq/RabbitMQLookupConnectionFactoryTest.java b/components/camel-rabbitmq/src/test/java/org/apache/camel/component/rabbitmq/RabbitMQLookupConnectionFactoryTest.java
new file mode 100644
index 0000000..438688c
--- /dev/null
+++ b/components/camel-rabbitmq/src/test/java/org/apache/camel/component/rabbitmq/RabbitMQLookupConnectionFactoryTest.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.rabbitmq;
+
+import com.rabbitmq.client.ConnectionFactory;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class RabbitMQLookupConnectionFactoryTest extends CamelTestSupport {
+
+ private ConnectionFactory myConnectionFactory;
+
+ protected JndiRegistry createRegistry() throws Exception {
+ myConnectionFactory = new ConnectionFactory();
+ myConnectionFactory.setHost("myhost");
+
+ JndiRegistry registry = super.createRegistry();
+ registry.bind("myConnectionFactory", myConnectionFactory);
+ return registry;
+ }
+
+ @Test
+ public void testLookupConnectionFactory() throws Exception {
+ RabbitMQEndpoint endpoint = context.getEndpoint("rabbitmq:myexchange", RabbitMQEndpoint.class);
+ assertNotNull(endpoint);
+ assertSame(endpoint.getConnectionFactory(), myConnectionFactory);
+ }
+
+}
diff --git a/examples/camel-example-rabbitmq/src/main/java/sample/camel/SampleCamelApplication.java b/examples/camel-example-rabbitmq/src/main/java/sample/camel/SampleCamelApplication.java
index 5d9304a..5839aad 100644
--- a/examples/camel-example-rabbitmq/src/main/java/sample/camel/SampleCamelApplication.java
+++ b/examples/camel-example-rabbitmq/src/main/java/sample/camel/SampleCamelApplication.java
@@ -16,8 +16,10 @@
*/
package sample.camel;
+import com.rabbitmq.client.ConnectionFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
//CHECKSTYLE:OFF
/**
@@ -33,5 +35,16 @@ public class SampleCamelApplication {
SpringApplication.run(SampleCamelApplication.class, args);
}
+ /* You can also configure the RabbitMQ ConnectionFactory using Java code style
+ @Bean
+ public ConnectionFactory rabbitConnectionFactory() {
+ ConnectionFactory cf = new ConnectionFactory();
+ cf.setHost("localhost");
+ cf.setPort(5672);
+ cf.setUsername("cameltest");
+ cf.setPassword("cameltest");
+ return cf;
+ }
+ */
}
//CHECKSTYLE:ON
diff --git a/examples/camel-example-rabbitmq/src/main/resources/application.properties b/examples/camel-example-rabbitmq/src/main/resources/application.properties
index 279b2cd..e414fc0 100644
--- a/examples/camel-example-rabbitmq/src/main/resources/application.properties
+++ b/examples/camel-example-rabbitmq/src/main/resources/application.properties
@@ -33,7 +33,8 @@ management.security.enabled = false
# turn on actuator health check
endpoints.health.enabled = true
-# configure connection to the rabbit mq broker
+# configure connection to the rabbit mq broker using camel-rabbitmq style
+# note you can also configure from Java code, see SampleCamelApplication.java
camel.component.rabbitmq.hostname=localhost
camel.component.rabbitmq.port-number=5672
camel.component.rabbitmq.username=guest
diff --git a/platforms/spring-boot/components-starter/camel-rabbitmq-starter/src/main/java/org/apache/camel/component/rabbitmq/springboot/RabbitMQComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-rabbitmq-starter/src/main/java/org/apache/camel/component/rabbitmq/springboot/RabbitMQComponentConfiguration.java
index 163f892..9bee754 100644
--- a/platforms/spring-boot/components-starter/camel-rabbitmq-starter/src/main/java/org/apache/camel/component/rabbitmq/springboot/RabbitMQComponentConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-rabbitmq-starter/src/main/java/org/apache/camel/component/rabbitmq/springboot/RabbitMQComponentConfiguration.java
@@ -17,8 +17,10 @@
package org.apache.camel.component.rabbitmq.springboot;
import javax.annotation.Generated;
+import com.rabbitmq.client.ConnectionFactory;
import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
/**
* The rabbitmq component allows you produce and consume messages from RabbitMQ
@@ -49,6 +51,20 @@ public class RabbitMQComponentConfiguration
*/
private String password = "guest";
/**
+ * To use a custom RabbitMQ connection factory. When this option is set, all
+ * connection options (connectionTimeout, requestedChannelMax...) set on URI
+ * are not used
+ */
+ @NestedConfigurationProperty
+ private ConnectionFactory connectionFactory;
+ /**
+ * Whether to auto-detect looking up RabbitMQ connection factory from the
+ * registry. When enabled and a single instance of the connection factory is
+ * found then it will be used. An explicit connection factory can be
+ * configured on the component or endpoint level which takes precedence.
+ */
+ private Boolean autoDetectConnectionFactory = true;
+ /**
* Whether the component should resolve property placeholders on itself when
* starting. Only properties which are of String type can use property
* placeholders.
@@ -87,6 +103,23 @@ public class RabbitMQComponentConfiguration
this.password = password;
}
+ public ConnectionFactory getConnectionFactory() {
+ return connectionFactory;
+ }
+
+ public void setConnectionFactory(ConnectionFactory connectionFactory) {
+ this.connectionFactory = connectionFactory;
+ }
+
+ public Boolean getAutoDetectConnectionFactory() {
+ return autoDetectConnectionFactory;
+ }
+
+ public void setAutoDetectConnectionFactory(
+ Boolean autoDetectConnectionFactory) {
+ this.autoDetectConnectionFactory = autoDetectConnectionFactory;
+ }
+
public Boolean getResolvePropertyPlaceholders() {
return resolvePropertyPlaceholders;
}
--
To stop receiving notification emails like this one, please contact
davsclaus@apache.org.