You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2011/10/20 17:04:21 UTC

svn commit: r1186842 - in /activemq/trunk: activemq-camel/src/test/java/org/apache/activemq/camel/ activemq-core/src/main/java/org/apache/activemq/ activemq-core/src/main/java/org/apache/activemq/broker/ activemq-core/src/main/java/org/apache/activemq/...

Author: tabish
Date: Thu Oct 20 15:04:21 2011
New Revision: 1186842

URL: http://svn.apache.org/viewvc?rev=1186842&view=rev
Log:
Fix for: https://issues.apache.org/jira/browse/AMQ-2240

URI options that are unmatched should result in an error 
to prevent subtle errors in configuration.

Added:
    activemq/trunk/activemq-camel/src/test/java/org/apache/activemq/camel/AMQ2240Test.java   (with props)
Modified:
    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java
    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/DefaultBrokerFactory.java
    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/URISupport.java

Added: activemq/trunk/activemq-camel/src/test/java/org/apache/activemq/camel/AMQ2240Test.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-camel/src/test/java/org/apache/activemq/camel/AMQ2240Test.java?rev=1186842&view=auto
==============================================================================
--- activemq/trunk/activemq-camel/src/test/java/org/apache/activemq/camel/AMQ2240Test.java (added)
+++ activemq/trunk/activemq-camel/src/test/java/org/apache/activemq/camel/AMQ2240Test.java Thu Oct 20 15:04:21 2011
@@ -0,0 +1,69 @@
+/**
+ * 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.activemq.camel;
+
+import static org.junit.Assert.*;
+
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.camel.component.ActiveMQComponent;
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AMQ2240Test {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AMQ2240Test.class);
+
+    @Test
+    public void testBadVMTransportOptionsJMSPrefix() throws Exception {
+
+        try{
+            final String vmUri = "vm://localhost?" +
+                "jms.redeliveryPolicy.maximumRedeliveries=0&" +
+                "jms.redeliveryPolicy.initialRedeliveryDelay=500&" +
+                "jms.useAsyncSend=false&jms.sendTimeout=ABC&" +
+                "jms.maxXXXXReconnectAttempts=1&jms.timeout=3000";
+
+            LOG.info("creating context with bad URI: " + vmUri);
+            ActiveMQComponent.activeMQComponent(vmUri);
+
+            fail("Should have received an exception from the bad URI.");
+        } catch(Exception e) {
+            // Expected
+        }
+    }
+
+    @Test
+    public void testBadVMTransportOptionsBrokerPrefix() throws Exception {
+        try{
+            final String vmUri = "vm://localhost?" +
+                "broker.XXX=foo&broker.persistent=XXX&broker.useJmx=false";
+
+            LOG.info("creating context with bad URI: " + vmUri);
+            ActiveMQComponent.activeMQComponent(vmUri).start();
+
+            fail("Should have received an exception from the bad URI.");
+        } catch(Exception e) {
+            // Expected
+        }
+    }
+}

Propchange: activemq/trunk/activemq-camel/src/test/java/org/apache/activemq/camel/AMQ2240Test.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java?rev=1186842&r1=1186841&r2=1186842&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java (original)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java Thu Oct 20 15:04:21 2011
@@ -52,8 +52,8 @@ import org.apache.activemq.util.URISuppo
  * Connections. <p/> This class also implements QueueConnectionFactory and
  * TopicConnectionFactory. You can use this connection to create both
  * QueueConnections and TopicConnections.
- * 
- * 
+ *
+ *
  * @see javax.jms.ConnectionFactory
  */
 public class ActiveMQConnectionFactory extends JNDIBaseStorable implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, StatsCapable, Cloneable {
@@ -237,7 +237,7 @@ public class ActiveMQConnectionFactory e
     /**
      * Creates a Transport based on this object's connection settings. Separated
      * from createActiveMQConnection to allow for subclasses to override.
-     * 
+     *
      * @return The newly created Transport.
      * @throws JMSException If unable to create trasnport.
      * @author sepandm@gmail.com
@@ -331,7 +331,7 @@ public class ActiveMQConnectionFactory e
             connection.addTransportListener(transportListener);
         }
         if (exceptionListener != null) {
-        	connection.setExceptionListener(exceptionListener);
+            connection.setExceptionListener(exceptionListener);
         }
         if (clientInternalExceptionListener != null) {
             connection.setClientInternalExceptionListener(clientInternalExceptionListener);
@@ -363,8 +363,18 @@ public class ActiveMQConnectionFactory e
             // It might be a standard URI or...
             try {
 
-                Map map = URISupport.parseQuery(this.brokerURL.getQuery());
-                if (buildFromMap(IntrospectionSupport.extractProperties(map, "jms."))) {
+                Map<String,String> map = URISupport.parseQuery(this.brokerURL.getQuery());
+                Map<String,Object> jmsOptionsMap = IntrospectionSupport.extractProperties(map, "jms.");
+                if (buildFromMap(jmsOptionsMap)) {
+                    if (!jmsOptionsMap.isEmpty()) {
+                        String msg = "There are " + jmsOptionsMap.size()
+                            + " jms options that couldn't be set on the ConnectionFactory."
+                            + " Check the options are spelled correctly."
+                            + " Unknown parameters=[" + jmsOptionsMap + "]."
+                            + " This connection factory cannot be started.";
+                        throw new IllegalArgumentException(msg);
+                    }
+
                     this.brokerURL = URISupport.createRemainingURI(this.brokerURL, map);
                 }
 
@@ -376,7 +386,17 @@ public class ActiveMQConnectionFactory e
             // It might be a composite URI.
             try {
                 CompositeData data = URISupport.parseComposite(this.brokerURL);
-                if (buildFromMap(IntrospectionSupport.extractProperties(data.getParameters(), "jms."))) {
+                Map<String,Object> jmsOptionsMap = IntrospectionSupport.extractProperties(data.getParameters(), "jms.");
+                if (buildFromMap(jmsOptionsMap)) {
+                    if (!jmsOptionsMap.isEmpty()) {
+                        String msg = "There are " + jmsOptionsMap.size()
+                            + " jms options that couldn't be set on the ConnectionFactory."
+                            + " Check the options are spelled correctly."
+                            + " Unknown parameters=[" + jmsOptionsMap + "]."
+                            + " This connection factory cannot be started.";
+                        throw new IllegalArgumentException(msg);
+                    }
+
                     this.brokerURL = data.toURI();
                 }
             } catch (URISyntaxException e) {
@@ -503,7 +523,7 @@ public class ActiveMQConnectionFactory e
 
     /**
      * Set true if always require messages to be sync sent
-     * 
+     *
      * @param alwaysSyncSend
      */
     public void setAlwaysSyncSend(boolean alwaysSyncSend) {
@@ -542,7 +562,7 @@ public class ActiveMQConnectionFactory e
      * Enables or disables whether or not queue consumers should be exclusive or
      * not for example to preserve ordering when not using <a
      * href="http://activemq.apache.org/message-groups.html">Message Groups</a>
-     * 
+     *
      * @param exclusiveConsumer
      */
     public void setExclusiveConsumer(boolean exclusiveConsumer) {
@@ -564,7 +584,7 @@ public class ActiveMQConnectionFactory e
     public MessageTransformer getTransformer() {
         return transformer;
     }
-    
+
     /**
      * @return the sendTimeout
      */
@@ -578,7 +598,7 @@ public class ActiveMQConnectionFactory e
     public void setSendTimeout(int sendTimeout) {
         this.sendTimeout = sendTimeout;
     }
-    
+
     /**
      * @return the sendAcksAsync
      */
@@ -592,7 +612,7 @@ public class ActiveMQConnectionFactory e
     public void setSendAcksAsync(boolean sendAcksAsync) {
         this.sendAcksAsync = sendAcksAsync;
     }
-    
+
     /**
      * @return the messagePrioritySupported
      */
@@ -617,6 +637,7 @@ public class ActiveMQConnectionFactory e
         this.transformer = transformer;
     }
 
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
     public void buildFromProperties(Properties properties) {
 
@@ -751,7 +772,7 @@ public class ActiveMQConnectionFactory e
      * minimize context switches which boost performance. However sometimes its
      * better to go slower to ensure that a single blocked consumer socket does
      * not block delivery to other consumers.
-     * 
+     *
      * @param asyncDispatch If true then consumers created on this connection
      *                will default to having their messages dispatched
      *                asynchronously. The default value is false.
@@ -841,7 +862,7 @@ public class ActiveMQConnectionFactory e
     /**
      * Sets the prefix used by autogenerated JMS Client ID values which are used
      * if the JMS client does not explicitly specify on.
-     * 
+     *
      * @param clientIDPrefix
      */
     public void setClientIDPrefix(String clientIDPrefix) {
@@ -941,12 +962,12 @@ public class ActiveMQConnectionFactory e
     public void setTransportListener(TransportListener transportListener) {
         this.transportListener = transportListener;
     }
-    
-    
+
+
     public ExceptionListener getExceptionListener() {
         return exceptionListener;
     }
-    
+
     /**
      * Allows an {@link ExceptionListener} to be configured on the ConnectionFactory so that when this factory
      * is used by frameworks which don't expose the Connection such as Spring JmsTemplate, you can register
@@ -957,37 +978,37 @@ public class ActiveMQConnectionFactory e
      * created by this factory
      */
     public void setExceptionListener(ExceptionListener exceptionListener) {
-    	this.exceptionListener = exceptionListener;
+        this.exceptionListener = exceptionListener;
     }
 
-	public int getAuditDepth() {
-		return auditDepth;
-	}
+    public int getAuditDepth() {
+        return auditDepth;
+    }
 
-	public void setAuditDepth(int auditDepth) {
-		this.auditDepth = auditDepth;
-	}
+    public void setAuditDepth(int auditDepth) {
+        this.auditDepth = auditDepth;
+    }
 
-	public int getAuditMaximumProducerNumber() {
-		return auditMaximumProducerNumber;
-	}
+    public int getAuditMaximumProducerNumber() {
+        return auditMaximumProducerNumber;
+    }
 
-	public void setAuditMaximumProducerNumber(int auditMaximumProducerNumber) {
-		this.auditMaximumProducerNumber = auditMaximumProducerNumber;
-	}
+    public void setAuditMaximumProducerNumber(int auditMaximumProducerNumber) {
+        this.auditMaximumProducerNumber = auditMaximumProducerNumber;
+    }
 
     public void setUseDedicatedTaskRunner(boolean useDedicatedTaskRunner) {
         this.useDedicatedTaskRunner = useDedicatedTaskRunner;
     }
-    
+
     public boolean isUseDedicatedTaskRunner() {
         return useDedicatedTaskRunner;
     }
-    
+
     public void setConsumerFailoverRedeliveryWaitPeriod(long consumerFailoverRedeliveryWaitPeriod) {
         this.consumerFailoverRedeliveryWaitPeriod = consumerFailoverRedeliveryWaitPeriod;
     }
-    
+
     public long getConsumerFailoverRedeliveryWaitPeriod() {
         return consumerFailoverRedeliveryWaitPeriod;
     }
@@ -995,7 +1016,7 @@ public class ActiveMQConnectionFactory e
     public ClientInternalExceptionListener getClientInternalExceptionListener() {
         return clientInternalExceptionListener;
     }
-    
+
     /**
      * Allows an {@link ClientInternalExceptionListener} to be configured on the ConnectionFactory so that when this factory
      * is used by frameworks which don't expose the Connection such as Spring JmsTemplate, you can register

Modified: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/DefaultBrokerFactory.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/DefaultBrokerFactory.java?rev=1186842&r1=1186841&r2=1186842&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/DefaultBrokerFactory.java (original)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/DefaultBrokerFactory.java Thu Oct 20 15:04:21 2011
@@ -28,8 +28,8 @@ import org.apache.activemq.util.URISuppo
  * Simple BrokerFactorySPI which using the brokerURI to extract the
  * configuration parameters for the broker service. This directly configures the
  * pojo model so there is no dependency on spring for configuration.
- * 
- * 
+ *
+ *
  */
 public class DefaultBrokerFactory implements BrokerFactoryHandler {
 
@@ -40,6 +40,15 @@ public class DefaultBrokerFactory implem
 
         BrokerService brokerService = new BrokerService();
         IntrospectionSupport.setProperties(brokerService, params);
+        if (!params.isEmpty()) {
+            String msg = "There are " + params.size()
+                + " Broker options that couldn't be set on the BrokerService."
+                + " Check the options are spelled correctly."
+                + " Unknown parameters=[" + params + "]."
+                + " This BrokerService cannot be started.";
+            throw new IllegalArgumentException(msg);
+        }
+
         if (compositeData.getPath() != null) {
             brokerService.setBrokerName(compositeData.getPath());
         }

Modified: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/URISupport.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/URISupport.java?rev=1186842&r1=1186841&r2=1186842&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/URISupport.java (original)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/URISupport.java Thu Oct 20 15:04:21 2011
@@ -24,12 +24,11 @@ import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 /**
- * 
+ * Utility class that provides methods for parsing URI's
  */
 public class URISupport {
 
@@ -105,7 +104,7 @@ public class URISupport {
         try {
             uri = uri.substring(uri.lastIndexOf("?") + 1); // get only the relevant part of the query
             Map<String, String> rc = new HashMap<String, String>();
-            if (uri != null) {
+            if (uri != null && !uri.isEmpty()) {
                 String[] parameters = uri.split("&");
                 for (int i = 0; i < parameters.length; i++) {
                     int p = parameters[i].indexOf("=");
@@ -134,7 +133,7 @@ public class URISupport {
             if (parameters.isEmpty()) {
                 parameters = emptyMap();
             }
-            
+
             return parameters;
         }
     }
@@ -159,7 +158,7 @@ public class URISupport {
         }
         return uri;
     }
-    
+
     @SuppressWarnings("unchecked")
     private static Map<String, String> emptyMap() {
         return Collections.EMPTY_MAP;
@@ -181,7 +180,7 @@ public class URISupport {
         int questionMark = schemeSpecificPart.lastIndexOf("?");
         // make sure question mark is not within parentheses
         if (questionMark < schemeSpecificPart.lastIndexOf(")")) {
-        	questionMark = -1;
+            questionMark = -1;
         }
         if (questionMark > 0) {
             schemeSpecificPart = schemeSpecificPart.substring(0, questionMark);
@@ -197,14 +196,14 @@ public class URISupport {
         CompositeData rc = new CompositeData();
         rc.scheme = uri.getScheme();
         String ssp = stripPrefix(uri.getRawSchemeSpecificPart().trim(), "//").trim();
-        
+
 
         parseComposite(uri, rc, ssp);
 
         rc.fragment = uri.getFragment();
         return rc;
     }
-    
+
     public static boolean isCompositeURI(URI uri) {
         if (uri.getQuery() != null) {
             return false;
@@ -322,18 +321,17 @@ public class URISupport {
         return new URI(stripPrefix(uri.getSchemeSpecificPart().trim(), "//"));
     }
 
-    public static String createQueryString(Map options) throws URISyntaxException {
+    public static String createQueryString(Map<String, String> options) throws URISyntaxException {
         try {
             if (options.size() > 0) {
                 StringBuffer rc = new StringBuffer();
                 boolean first = true;
-                for (Iterator iter = options.keySet().iterator(); iter.hasNext();) {
+                for (String key : options.keySet()) {
                     if (first) {
                         first = false;
                     } else {
                         rc.append("&");
                     }
-                    String key = (String)iter.next();
                     String value = (String)options.get(key);
                     rc.append(URLEncoder.encode(key, "UTF-8"));
                     rc.append("=");
@@ -350,10 +348,10 @@ public class URISupport {
 
     /**
      * Creates a URI from the original URI and the remaining paramaters
-     * 
+     *
      * @throws URISyntaxException
      */
-    public static URI createRemainingURI(URI originalURI, Map params) throws URISyntaxException {
+    public static URI createRemainingURI(URI originalURI, Map<String, String> params) throws URISyntaxException {
         String s = createQueryString(params);
         if (s.length() == 0) {
             s = null;