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 2008/01/26 22:29:34 UTC

svn commit: r615499 - in /activemq/activemq-cpp/trunk/src: main/activemq/transport/ main/activemq/util/ test/activemq/util/

Author: tabish
Date: Sat Jan 26 13:29:32 2008
New Revision: 615499

URL: http://svn.apache.org/viewvc?rev=615499&view=rev
Log:
http://issues.apache.org/activemq/browse/AMQCPP-148

Support added and tested env var syntax is ${<VALUE>}

Modified:
    activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.cpp
    activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.h
    activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp
    activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h
    activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp
    activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h

Modified: activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.cpp?rev=615499&r1=615498&r2=615499&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.cpp (original)
+++ activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.cpp Sat Jan 26 13:29:32 2008
@@ -21,11 +21,13 @@
 #include <activemq/transport/TransportFactory.h>
 #include <activemq/transport/TransportFactoryMap.h>
 #include <activemq/exceptions/ActiveMQException.h>
+#include <activemq/util/URISupport.h>
 
 using namespace std;
 using namespace activemq;
 using namespace activemq::exceptions;
 using namespace activemq::transport;
+using namespace activemq::util;
 using namespace decaf;
 using namespace decaf::util;
 using namespace decaf::lang;
@@ -33,7 +35,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 Transport* TransportBuilder::buildTransport( const std::string& url,
-                                             util::Properties& properties )
+                                             decaf::util::Properties& properties )
     throw ( cms::CMSException ) {
 
     try{
@@ -41,7 +43,7 @@
         Transport* transport = NULL;
 
         // Parse out the properties from the URI
-        parseURL( url, properties );
+        URISupport::parseURL( url, properties );
 
         // Create the Base IO Transport
         transport = this->createTransport(
@@ -81,64 +83,8 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void TransportBuilder::parseURL( const std::string& URI,
-                                 util::Properties& properties )
-    throw ( decaf::lang::exceptions::IllegalArgumentException ) {
-
-    try{
-
-        StringTokenizer tokenizer( URI, ":/" );
-
-        std::vector<std::string> tokens;
-
-        // Require that there be three tokens at the least, these are
-        // transport, url, port.
-        if( tokenizer.countTokens() < 3 ) {
-            throw decaf::lang::exceptions::IllegalArgumentException(
-                __FILE__, __LINE__,
-                (string( "TransportBuilder::parseURL - "
-                         "Marlformed URI: ") + URI).c_str() );
-        }
-
-        // First element should be the Transport Type, following that is the
-        // URL and any params.
-        properties.setProperty( "transport.protocol", tokenizer.nextToken() );
-
-        // Parse URL and Port as one item, optional params follow the ?
-        // and then each param set is delimited with & we extract first
-        // three chars as they are the left over ://
-        properties.setProperty( "transport.uri", tokenizer.nextToken("&?").substr(3) );
-
-        // Now get all the optional parameters and store them as properties
-        int count = tokenizer.toArray( tokens );
-
-        for( int i = 0; i < count; ++i ) {
-            tokenizer.reset( tokens[i], "=" );
-
-            if( tokenizer.countTokens() != 2 ) {
-                throw decaf::lang::exceptions::IllegalArgumentException(
-                    __FILE__, __LINE__,
-                    ( string( "TransportBuilder::parseURL - "
-                              "Marlformed Parameter = " ) + tokens[i] ).c_str() );
-            }
-
-            // Get them in order, passing both as nextToken calls in the
-            // set Property can cause reversed order.
-            string key = tokenizer.nextToken();
-            string value = tokenizer.nextToken();
-
-            // Store this param as a property
-            properties.setProperty( key, value );
-        }
-    }
-    AMQ_CATCH_RETHROW( IllegalArgumentException )
-    AMQ_CATCH_EXCEPTION_CONVERT( ActiveMQException, IllegalArgumentException )
-    AMQ_CATCHALL_THROW( IllegalArgumentException )
-}
-
-////////////////////////////////////////////////////////////////////////////////
 Transport* TransportBuilder::createTransport( const std::string& name,
-                                              const util::Properties& properties,
+                                              const decaf::util::Properties& properties,
                                               Transport* next )
     throw ( cms::CMSException ) {
 
@@ -147,6 +93,7 @@
         // Create the Transport that the Connector will use.
         TransportFactory* factory =
             TransportFactoryMap::getInstance().lookup( name );
+
         if( factory == NULL ){
             throw ActiveMQException(
                 __FILE__, __LINE__,

Modified: activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.h?rev=615499&r1=615498&r2=615499&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.h (original)
+++ activemq/activemq-cpp/trunk/src/main/activemq/transport/TransportBuilder.h Sat Jan 26 13:29:32 2008
@@ -54,17 +54,6 @@
     protected:
 
         /**
-         * Parses the properties out of the provided Broker URI and sets
-         * them in the passed Properties Object.
-         * @param URI a Broker URI to parse
-         * @param properties a Properties object to set the parsed values in
-         * @throws IllegalArgumentException if the passed URI is invalid
-         */
-        virtual void parseURL( const std::string& URI,
-                               decaf::util::Properties& properties )
-            throw ( decaf::lang::exceptions::IllegalArgumentException );
-
-        /**
          * Given a Transport Name and the properties it should use to configure
          * itself, create it.  If the name cannot be linked to a transport
          * factory then an exception is thrown.

Modified: activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp?rev=615499&r1=615498&r2=615499&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp (original)
+++ activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp Sat Jan 26 13:29:32 2008
@@ -21,7 +21,9 @@
 
 #include <decaf/util/StringTokenizer.h>
 #include <decaf/lang/exceptions/IllegalArgumentException.h>
+#include <decaf/lang/System.h>
 
+using namespace std;
 using namespace activemq;
 using namespace activemq::util;
 using namespace decaf::util;
@@ -29,6 +31,62 @@
 using namespace decaf::lang::exceptions;
 
 ////////////////////////////////////////////////////////////////////////////////
+void URISupport::parseURL( const std::string& URI,
+                           decaf::util::Properties& properties )
+    throw ( decaf::lang::exceptions::IllegalArgumentException ) {
+
+    try{
+
+        StringTokenizer tokenizer( URI, ":/" );
+
+        std::vector<std::string> tokens;
+
+        // Require that there be three tokens at the least, these are
+        // transport, url, port.
+        if( tokenizer.countTokens() < 3 ) {
+            throw decaf::lang::exceptions::IllegalArgumentException(
+                __FILE__, __LINE__,
+                (string( "URISupport::parseURL - "
+                         "Marlformed URI: ") + URI).c_str() );
+        }
+
+        // First element should be the Transport Type, following that is the
+        // URL and any params.
+        properties.setProperty( "transport.protocol", tokenizer.nextToken() );
+
+        // Parse URL and Port as one item, optional params follow the ?
+        // and then each param set is delimited with & we extract first
+        // three chars as they are the left over ://
+        properties.setProperty( "transport.uri", tokenizer.nextToken("&?").substr(3) );
+
+        // Now get all the optional parameters and store them as properties
+        int count = tokenizer.toArray( tokens );
+
+        for( int i = 0; i < count; ++i ) {
+            tokenizer.reset( tokens[i], "=" );
+
+            if( tokenizer.countTokens() != 2 ) {
+                throw decaf::lang::exceptions::IllegalArgumentException(
+                    __FILE__, __LINE__,
+                    ( string( "URISupport::parseURL - "
+                              "Marlformed Parameter = " ) + tokens[i] ).c_str() );
+            }
+
+            // Get them in order, passing both as nextToken calls in the
+            // set Property can cause reversed order.
+            string key = tokenizer.nextToken();
+            string value = URISupport::replaceEnvValues( tokenizer.nextToken() );
+
+            // Store this param as a property
+            properties.setProperty( key, value );
+        }
+    }
+    AMQ_CATCH_RETHROW( IllegalArgumentException )
+    AMQ_CATCH_EXCEPTION_CONVERT( Exception, IllegalArgumentException )
+    AMQ_CATCHALL_THROW( IllegalArgumentException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
 Properties URISupport::parseQuery( std::string query )
     throw ( IllegalArgumentException ) {
 
@@ -91,12 +149,50 @@
 
             // Get the Value
             if( tokenizer.hasMoreTokens() != false ) {
-                value = tokenizer.nextToken();
+                value = URISupport::replaceEnvValues( tokenizer.nextToken() );
             }
 
             // Store them.
             properties->setProperty( key, value );
         }
+    }
+    AMQ_CATCH_RETHROW( IllegalArgumentException )
+    AMQ_CATCH_EXCEPTION_CONVERT( Exception, IllegalArgumentException )
+    AMQ_CATCHALL_THROW( IllegalArgumentException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string URISupport::replaceEnvValues( const std::string& value )
+    throw ( decaf::lang::exceptions::IllegalArgumentException ) {
+
+    try {
+
+        // If it matches the first env var indicator then we validate that it is
+        // surrounded by an { and } bracket.  once done we remove the inner value
+        // and look up the env var.
+        if( value.at(0) == '$' ) {
+
+            if( value.size() > 3 && value.at(1) != '{' && value.at( value.size() - 1 ) != '}' ) {
+                throw new decaf::lang::exceptions::IllegalArgumentException(
+                    __FILE__, __LINE__,
+                    "URISupport::replaceEnvValues - Invalid Env Var Syntax: %s",
+                    value.c_str() );
+            }
+
+            string var = value.substr( 2, value.size() - 3 );
+            var = decaf::lang::System::getenv( var );
+
+            if( var == "" ) {
+                throw new decaf::lang::exceptions::IllegalArgumentException(
+                    __FILE__, __LINE__,
+                    "URISupport::replaceEnvValues - Env Var not set: %s",
+                    value.c_str() );
+            }
+
+            return var;
+        }
+
+        return value;
     }
     AMQ_CATCH_RETHROW( IllegalArgumentException )
     AMQ_CATCH_EXCEPTION_CONVERT( Exception, IllegalArgumentException )

Modified: activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h?rev=615499&r1=615498&r2=615499&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h (original)
+++ activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h Sat Jan 26 13:29:32 2008
@@ -30,6 +30,17 @@
         virtual ~URISupport();
 
         /**
+         * Parses the properties out of the provided Broker URI and sets
+         * them in the passed Properties Object.
+         * @param URI a Broker URI to parse
+         * @param properties a Properties object to set the parsed values in
+         * @throws IllegalArgumentException if the passed URI is invalid
+         */
+        static void parseURL( const std::string& URI,
+                              decaf::util::Properties& properties )
+            throw ( decaf::lang::exceptions::IllegalArgumentException );
+
+        /**
          * Parse the Query portion of a URI String and return a Simple
          * Properties object containing the parameter names as keys, and
          * the parameter values and values of the Properties.
@@ -48,6 +59,20 @@
          */
         static void parseQuery( std::string query,
                                 decaf::util::Properties* properties )
+            throw ( decaf::lang::exceptions::IllegalArgumentException );
+
+    private:
+
+        /**
+         * Accepts a string value and checks to see if that value is of the
+         * form ${XXX} which is our accepted form for environment variables.
+         * If so the we attempt to replace the value with what is stored in that
+         * env var, if the var is not set then we throw an IllegalArgumentException.
+         * @param value - the value to check for env
+         * @returns the env var if value points to an env var else returns value
+         * @throws IllegalArgumentException if the var is not set or has bad syntax
+         */
+        static std::string replaceEnvValues( const std::string& value )
             throw ( decaf::lang::exceptions::IllegalArgumentException );
 
     };

Modified: activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp?rev=615499&r1=615498&r2=615499&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp (original)
+++ activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp Sat Jan 26 13:29:32 2008
@@ -21,6 +21,8 @@
 
 #include <activemq/util/URISupport.h>
 #include <decaf/util/Properties.h>
+#include <decaf/lang/System.h>
+#include <decaf/lang/exceptions/IllegalArgumentException.h>
 
 using namespace std;
 using namespace decaf;
@@ -29,8 +31,8 @@
 using namespace activemq::util;
 
 ////////////////////////////////////////////////////////////////////////////////
-void URISupportTest::test()
-{
+void URISupportTest::test() {
+
     string test = "?option1=test1&option2=test2";
 
     Properties map = URISupport::parseQuery( test );
@@ -67,3 +69,56 @@
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+void URISupportTest::testURIParseEnv() {
+
+    string test = "tcp://localhost:61616?option1=test1&option2=test2";
+
+    Properties map;
+
+    URISupport::parseURL( test, map );
+
+    CPPUNIT_ASSERT( map.hasProperty( "option1" ) == true );
+    CPPUNIT_ASSERT( map.hasProperty( "option2" ) == true );
+
+    CPPUNIT_ASSERT( map.getProperty( "option1", "" ) == "test1" );
+    CPPUNIT_ASSERT( map.getProperty( "option2", "" ) == "test2" );
+
+    decaf::lang::System::setenv( "TEST_CPP_AMQ", "test2" );
+
+    test = "tcp://localhost:61616?option1=test1&option2=${TEST_CPP_AMQ}";
+    map.clear();
+    URISupport::parseURL( test, map );
+    CPPUNIT_ASSERT( map.hasProperty( "option2" ) == true );
+    CPPUNIT_ASSERT( map.getProperty( "option2", "" ) == "test2" );
+
+    test = "tcp://localhost:61616?option1=test1&option2=${TEST_CPP_AMQ_XXX}";
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should Throw an IllegalArgumentException",
+        URISupport::parseURL( test, map ),
+        decaf::lang::exceptions::IllegalArgumentException );
+
+    test = "tcp://localhost:61616?option1=test1&option2=${}";
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should Throw an IllegalArgumentException",
+        URISupport::parseURL( test, map ),
+        decaf::lang::exceptions::IllegalArgumentException );
+
+    test = "tcp://localhost:61616?option1=test1&option2=$X}";
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should Throw an IllegalArgumentException",
+        URISupport::parseURL( test, map ),
+        decaf::lang::exceptions::IllegalArgumentException );
+
+    test = "tcp://localhost:61616?option1=test1&option2=${X";
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should Throw an IllegalArgumentException",
+        URISupport::parseURL( test, map ),
+        decaf::lang::exceptions::IllegalArgumentException );
+
+    test = "tcp://localhost:61616?option1=test1&option2=$X";
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should Throw an IllegalArgumentException",
+        URISupport::parseURL( test, map ),
+        decaf::lang::exceptions::IllegalArgumentException );
+}

Modified: activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h?rev=615499&r1=615498&r2=615499&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h (original)
+++ activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h Sat Jan 26 13:29:32 2008
@@ -23,20 +23,22 @@
 
 namespace activemq{
 namespace util{
-    
-    class URISupportTest : public CppUnit::TestFixture { 
+
+    class URISupportTest : public CppUnit::TestFixture {
 
        CPPUNIT_TEST_SUITE( URISupportTest );
        CPPUNIT_TEST( test );
+       CPPUNIT_TEST( testURIParseEnv );
        CPPUNIT_TEST_SUITE_END();
 
     public:
-    
+
         URISupportTest() {}
         virtual ~URISupportTest() {}
-        
+
         void test();
-        
+        void testURIParseEnv();
+
     };
 
 }}