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 2012/11/20 14:54:37 UTC

svn commit: r1411664 - in /camel/trunk/components/camel-jms/src: main/java/org/apache/camel/component/jms/reply/ test/java/org/apache/camel/component/jms/

Author: davsclaus
Date: Tue Nov 20 13:54:36 2012
New Revision: 1411664

URL: http://svn.apache.org/viewvc?rev=1411664&view=rev
Log:
CAMEL-5809: camel-jms request/reply over JMS allow to use concurrentConsumers/maxConcurrentConsumers options.

Added:
    camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsRequestReplyExclusiveReplyToConcurrentTest.java
      - copied, changed from r1411576, camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsRequestReplyExclusiveReplyToTest.java
Modified:
    camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/MessageSelectorCreator.java
    camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/PersistentQueueReplyManager.java
    camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/TemporaryQueueReplyManager.java

Modified: camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/MessageSelectorCreator.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/MessageSelectorCreator.java?rev=1411664&r1=1411663&r2=1411664&view=diff
==============================================================================
--- camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/MessageSelectorCreator.java (original)
+++ camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/MessageSelectorCreator.java Tue Nov 20 13:54:36 2012
@@ -29,7 +29,7 @@ public class MessageSelectorCreator impl
     protected static final Logger LOG = LoggerFactory.getLogger(MessageSelectorCreator.class);
     protected final CorrelationTimeoutMap timeoutMap;
     protected final ConcurrentSkipListSet<String> correlationIds;
-    protected boolean dirty = true;
+    protected volatile boolean dirty = true;
     protected StringBuilder expression;
 
     public MessageSelectorCreator(CorrelationTimeoutMap timeoutMap) {

Modified: camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/PersistentQueueReplyManager.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/PersistentQueueReplyManager.java?rev=1411664&r1=1411663&r2=1411664&view=diff
==============================================================================
--- camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/PersistentQueueReplyManager.java (original)
+++ camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/PersistentQueueReplyManager.java Tue Nov 20 13:54:36 2012
@@ -174,8 +174,10 @@ public class PersistentQueueReplyManager
         answer.setMessageListener(this);
         answer.setPubSubDomain(false);
         answer.setSubscriptionDurable(false);
-        answer.setConcurrentConsumers(1);
-        answer.setMaxConcurrentConsumers(1);
+        answer.setConcurrentConsumers(endpoint.getConcurrentConsumers());
+        if (endpoint.getMaxConcurrentConsumers() > 0) {
+            answer.setMaxConcurrentConsumers(endpoint.getMaxConcurrentConsumers());
+        }
         answer.setConnectionFactory(endpoint.getConnectionFactory());
         String clientId = endpoint.getClientId();
         if (clientId != null) {
@@ -205,8 +207,20 @@ public class PersistentQueueReplyManager
 
         // setup a bean name which is used ny Spring JMS as the thread name
         String name = "PersistentQueueReplyManager[" + answer.getDestinationName() + "]";
-        name = endpoint.getCamelContext().getExecutorServiceManager().resolveThreadName(name);
-        answer.setBeanName(name);
+        String beanName = endpoint.getCamelContext().getExecutorServiceManager().resolveThreadName(name);
+        answer.setBeanName(beanName);
+
+        if (answer.getConcurrentConsumers() > 1) {
+            if (ReplyToType.Shared == type) {
+                // warn if using concurrent consumer with shared reply queue as that may not work properly
+                log.warn("Using {}-{} concurrent consumer on {} with shared queue {} may not work properly with all message brokers.",
+                        new Object[]{answer.getConcurrentConsumers(), answer.getMaxConcurrentConsumers(), name, endpoint.getReplyTo()});
+            } else {
+                // log that we are using concurrent consumers
+                log.info("Using {}-{} concurrent consumers on {}",
+                        new Object[]{answer.getConcurrentConsumers(), answer.getMaxConcurrentConsumers(), name});
+            }
+        }
 
         return answer;
     }

Modified: camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/TemporaryQueueReplyManager.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/TemporaryQueueReplyManager.java?rev=1411664&r1=1411663&r2=1411664&view=diff
==============================================================================
--- camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/TemporaryQueueReplyManager.java (original)
+++ camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/reply/TemporaryQueueReplyManager.java Tue Nov 20 13:54:36 2012
@@ -102,8 +102,10 @@ public class TemporaryQueueReplyManager 
         answer.setMessageListener(this);
         answer.setPubSubDomain(false);
         answer.setSubscriptionDurable(false);
-        answer.setConcurrentConsumers(1);
-        answer.setMaxConcurrentConsumers(1);
+        answer.setConcurrentConsumers(endpoint.getConcurrentConsumers());
+        if (endpoint.getMaxConcurrentConsumers() > 0) {
+            answer.setMaxConcurrentConsumers(endpoint.getMaxConcurrentConsumers());
+        }
         answer.setConnectionFactory(endpoint.getConnectionFactory());
         String clientId = endpoint.getClientId();
         if (clientId != null) {
@@ -133,9 +135,14 @@ public class TemporaryQueueReplyManager 
 
         // setup a bean name which is used ny Spring JMS as the thread name
         String name = "TemporaryQueueReplyManager[" + answer.getDestinationName() + "]";
-        name = endpoint.getCamelContext().getExecutorServiceManager().resolveThreadName(name);
-        answer.setBeanName(name);
+        String beanName = endpoint.getCamelContext().getExecutorServiceManager().resolveThreadName(name);
+        answer.setBeanName(beanName);
 
+        if (answer.getConcurrentConsumers() > 1) {
+            // log that we are using concurrent consumers
+            log.info("Using {}-{} concurrent consumers on {}",
+                    new Object[]{answer.getConcurrentConsumers(), answer.getMaxConcurrentConsumers(), name});
+        }
         return answer;
     }
 

Copied: camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsRequestReplyExclusiveReplyToConcurrentTest.java (from r1411576, camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsRequestReplyExclusiveReplyToTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsRequestReplyExclusiveReplyToConcurrentTest.java?p2=camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsRequestReplyExclusiveReplyToConcurrentTest.java&p1=camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsRequestReplyExclusiveReplyToTest.java&r1=1411576&r2=1411664&rev=1411664&view=diff
==============================================================================
--- camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsRequestReplyExclusiveReplyToTest.java (original)
+++ camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsRequestReplyExclusiveReplyToConcurrentTest.java Tue Nov 20 13:54:36 2012
@@ -16,11 +16,13 @@
  */
 package org.apache.camel.component.jms;
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 import javax.jms.ConnectionFactory;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.CamelExecutionException;
-import org.apache.camel.FailedToCreateProducerException;
+import org.apache.camel.builder.NotifyBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.apache.camel.util.StopWatch;
@@ -29,37 +31,41 @@ import org.junit.Test;
 import static org.apache.camel.component.jms.JmsComponent.jmsComponentAutoAcknowledge;
 
 /**
- * Using exclusive fixed replyTo queues should be faster as there is no need for
- * JMSMessage selectors.
- *
- * @version 
+ * @version
  */
-public class JmsRequestReplyExclusiveReplyToTest extends CamelTestSupport {
+public class JmsRequestReplyExclusiveReplyToConcurrentTest extends CamelTestSupport {
+
+    private int size = 100;
 
     @Test
     public void testJmsRequestReplyExclusiveFixedReplyTo() throws Exception {
+        NotifyBuilder builder = new NotifyBuilder(context).from("direct:start").whenDone(size).create();
+
         StopWatch watch = new StopWatch();
+        ExecutorService executor = Executors.newFixedThreadPool(10);
+        for (int i = 0; i < size; i++) {
+            final Integer num = i;
+            executor.submit(new Runnable() {
+                @Override
+                public void run() {
+                    String reply = template.requestBody("direct:start", "" + num, String.class);
+                    log.info("Sent {} expecting reply 'Hello {}' got --> {}", new Object[]{num, num, reply});
+                    assertNotNull(reply);
+                    assertEquals("Hello " + num, reply);
+                }
+            });
+        }
 
-        assertEquals("Hello A", template.requestBody("activemq:queue:foo?replyTo=bar&replyToType=Exclusive", "A"));
-        assertEquals("Hello B", template.requestBody("activemq:queue:foo?replyTo=bar&replyToType=Exclusive", "B"));
-        assertEquals("Hello C", template.requestBody("activemq:queue:foo?replyTo=bar&replyToType=Exclusive", "C"));
-        assertEquals("Hello D", template.requestBody("activemq:queue:foo?replyTo=bar&replyToType=Exclusive", "D"));
-        assertEquals("Hello E", template.requestBody("activemq:queue:foo?replyTo=bar&replyToType=Exclusive", "E"));
+        log.info("Waiting to process {} messages...", size);
+        assertTrue(builder.matches(60, TimeUnit.SECONDS));
 
         long delta = watch.stop();
-        assertTrue("Should be faster than about 4 seconds, was: " + delta, delta < 4200);
-    }
+        log.info("Took {} millis", delta);
 
-    @Test
-    public void testInvalidConfiguration() throws Exception {
-        try {
-            template.requestBody("activemq:queue:foo?replyTo=bar&replyToType=Temporary", "Hello World");
-            fail("Should have thrown exception");
-        } catch (CamelExecutionException e) {
-            assertIsInstanceOf(FailedToCreateProducerException.class, e.getCause());
-            assertIsInstanceOf(IllegalArgumentException.class, e.getCause().getCause());
-            assertEquals("ReplyToType Temporary is not supported when replyTo bar is also configured.", e.getCause().getCause().getMessage());
-        }
+        // just sleep a bit before shutting down
+        Thread.sleep(1000);
+
+        executor.shutdownNow();
     }
 
     protected CamelContext createCamelContext() throws Exception {
@@ -74,7 +80,12 @@ public class JmsRequestReplyExclusiveRep
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("activemq:queue:foo")
+                from("direct:start")
+                    .to("activemq:queue:foo?replyTo=bar&replyToType=Exclusive&concurrentConsumers=5&maxConcurrentConsumers=10")
+                    .to("log:reply")
+                    .to("mock:reply");
+
+                from("activemq:queue:foo?concurrentConsumers=5&maxConcurrentConsumers=10")
                     .transform(body().prepend("Hello "));
             }
         };