activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject git commit: https://issues.apache.org/jira/browse/AMQCPP-511
Date Thu, 17 Oct 2013 21:59:57 GMT
Updated Branches:
  refs/heads/trunk f71491091 -> 9c8ab0328


https://issues.apache.org/jira/browse/AMQCPP-511

Implement an AbstractDiscoveryAgentFactory and more tests of the
discovery agent bits. 

Project: http://git-wip-us.apache.org/repos/asf/activemq-cpp/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-cpp/commit/9c8ab032
Tree: http://git-wip-us.apache.org/repos/asf/activemq-cpp/tree/9c8ab032
Diff: http://git-wip-us.apache.org/repos/asf/activemq-cpp/diff/9c8ab032

Branch: refs/heads/trunk
Commit: 9c8ab03285d1417a3058ad1755de3f67fdb2df2f
Parents: f714910
Author: Timothy Bish <tabish121@gmai.com>
Authored: Thu Oct 17 17:59:54 2013 -0400
Committer: Timothy Bish <tabish121@gmai.com>
Committed: Thu Oct 17 17:59:54 2013 -0400

----------------------------------------------------------------------
 activemq-cpp/src/main/Makefile.am               |   2 +
 .../discovery/AbstractDiscoveryAgent.cpp        |  39 ++++-
 .../discovery/AbstractDiscoveryAgent.h          |  95 +++++++++++-
 .../discovery/AbstractDiscoveryAgentFactory.cpp |  81 +++++++++++
 .../discovery/AbstractDiscoveryAgentFactory.h   |  89 ++++++++++++
 activemq-cpp/src/test/Makefile.am               |   4 +
 .../AbstractDiscoveryAgentFactoryTest.cpp       | 112 ++++++++++++++
 .../AbstractDiscoveryAgentFactoryTest.h         |  45 ++++++
 .../discovery/AbstractDiscoveryAgentTest.cpp    | 145 +++++++++++++++++++
 .../discovery/AbstractDiscoveryAgentTest.h      |  45 ++++++
 activemq-cpp/src/test/testRegistry.cpp          |   4 +
 11 files changed, 657 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/main/Makefile.am
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/Makefile.am b/activemq-cpp/src/main/Makefile.am
index a34c1c8..19f33d4 100644
--- a/activemq-cpp/src/main/Makefile.am
+++ b/activemq-cpp/src/main/Makefile.am
@@ -156,6 +156,7 @@ cc_sources = \
     activemq/transport/TransportRegistry.cpp \
     activemq/transport/correlator/ResponseCorrelator.cpp \
     activemq/transport/discovery/AbstractDiscoveryAgent.cpp \
+    activemq/transport/discovery/AbstractDiscoveryAgentFactory.cpp \
     activemq/transport/discovery/DiscoveredBrokerData.cpp \
     activemq/transport/discovery/DiscoveryAgent.cpp \
     activemq/transport/discovery/DiscoveryAgentFactory.cpp \
@@ -813,6 +814,7 @@ h_sources = \
     activemq/transport/TransportRegistry.h \
     activemq/transport/correlator/ResponseCorrelator.h \
     activemq/transport/discovery/AbstractDiscoveryAgent.h \
+    activemq/transport/discovery/AbstractDiscoveryAgentFactory.h \
     activemq/transport/discovery/DiscoveredBrokerData.h \
     activemq/transport/discovery/DiscoveryAgent.h \
     activemq/transport/discovery/DiscoveryAgentFactory.h \

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.cpp
b/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.cpp
index 4bb0821..eb6203a 100644
--- a/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.cpp
+++ b/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.cpp
@@ -104,6 +104,25 @@ namespace discovery {
                                        reportAdvertizeFailed(true)
         {}
 
+        ~AbstractDiscoveryAgentImpl() {
+            if (started.compareAndSet(true, false)) {
+                if (worker == NULL) {
+                    worker->join(5000);
+
+                    if (!worker->isAlive()) {
+                        worker->interrupt();
+                        worker->join(1000);
+                    }
+
+                    worker.reset(NULL);
+                }
+
+                executor->shutdown();
+                executor->awaitTermination(1, TimeUnit::MINUTES);
+            }
+
+        }
+
         Executor& getExecutor() {
             if (executor == NULL) {
                 synchronized(&discoveredServicesLock) {
@@ -197,7 +216,7 @@ namespace discovery {
         ServiceAddedRunnable(AbstractDiscoveryAgent* agent, Pointer<DiscoveredBrokerData>
event) :
             Runnable(), agent(agent), event(event) {
         }
-        virtual ~ServiceAddedRunnable();
+        virtual ~ServiceAddedRunnable() {}
 
         virtual void run() {
             DiscoveryListener* listener = agent->getDiscoveryListener();
@@ -217,7 +236,7 @@ namespace discovery {
 
         ServiceRemovedRunnable(AbstractDiscoveryAgent* agent, Pointer<DiscoveredBrokerData>
event) :
             Runnable(), agent(agent), event(event) {}
-        virtual ~ServiceRemovedRunnable();
+        virtual ~ServiceRemovedRunnable() {}
 
         virtual void run() {
             DiscoveryListener* listener = agent->getDiscoveryListener();
@@ -242,6 +261,11 @@ AbstractDiscoveryAgent::~AbstractDiscoveryAgent() {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+bool AbstractDiscoveryAgent::isStarted() const {
+    return impl->started.get();
+}
+
+////////////////////////////////////////////////////////////////////////////////
 void AbstractDiscoveryAgent::start() {
     if (impl->started.compareAndSet(false, true)) {
         doStart();
@@ -266,6 +290,7 @@ void AbstractDiscoveryAgent::stop() {
 
             if (!impl->worker->isAlive()) {
                 impl->worker->interrupt();
+                impl->worker->join(WORKER_KILL_TIME_SECONDS);
             }
 
             impl->worker.reset(NULL);
@@ -394,6 +419,16 @@ bool AbstractDiscoveryAgent::isUseExponentialBackOff() const {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+void AbstractDiscoveryAgent::setBackOffMultiplier(long long multiplier) {
+    impl->backOffMultiplier = multiplier;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long AbstractDiscoveryAgent::getBackOffMultiplier() const {
+    return impl->backOffMultiplier;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 void AbstractDiscoveryAgent::setGroup(const std::string& group) {
     impl->group = group;
 }

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.h b/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.h
index 58582f2..acab62e 100644
--- a/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.h
+++ b/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgent.h
@@ -72,6 +72,11 @@ namespace discovery {
         virtual DiscoveryListener* getDiscoveryListener() const;
 
         /**
+         * @returns true if this agent is currently started.
+         */
+        bool isStarted() const;
+
+        /**
          * Sets the service that is publish by this agent if it supports publishing.
          *
          * @param name
@@ -112,7 +117,7 @@ namespace discovery {
          * @param multiplier
          *      The back multiplier to use when calculating the next recovery time.
          */
-        void getBackOffMultiplier(long long multiplier);
+        void setBackOffMultiplier(long long multiplier);
 
         /**
          * Gets the configured backoff multiplier for calculating the next recovery time.
@@ -121,30 +126,100 @@ namespace discovery {
          */
         long long getBackOffMultiplier() const;
 
+        /**
+         * Sets the initial amount of time the agent should wait before attempt a reconnect
on
+         * a discovered service.
+         *
+         * @param initialReconnectDelay
+         *      The time to wait before the initial reconnect attempt in milliseconds.
+         */
         void setInitialReconnectDelay(long long initialReconnectDelay);
 
+        /**
+         * Gets the initial amount of time the agent should wait before attempt a reconnect
on
+         * a discovered service.
+         *
+         * @returns The time to wait before the initial reconnect attempt in milliseconds.
+         */
         long long getInitialReconnectDelay() const;
 
+        /**
+         * Sets the maximum number of reconnect attempts that occur before a service is considered
to
+         * be failed and removed.
+         *
+         * @param maxReconnectAttempts
+         *      The maximum number of reconnect attempts allowed or zero for no limit.
+         */
         void setMaxReconnectAttempts(int maxReconnectAttempts);
 
+        /**
+         * Returns the maximum number of reconnect attempts that will be attempted before
a
+         * service is considered to be failed.
+         *
+         * @returns the maximum number of allowed reconnect attempts.
+         */
         int getMaxReconnectAttempts() const;
 
+        /**
+         * The maximum time that a reconnect delay is allowed to grow to, in Milliseconds.
+         *
+         * @param maxReconnectDelay
+         *      The maximum time in milliseconds to limit the reconnect delays.
+         */
         void setMaxReconnectDelay(long long maxReconnectDelay);
 
+        /**
+         * Returns the maximum time allowed between reconnect attempts.  This limits the
amount
+         * of time that reconnect will wait when exponential backoff is enabled.
+         *
+         * @returns the maximum reconnect delay in milliseconds.
+         */
         long long getMaxReconnectDelay() const;
 
+        /**
+         * Sets whether reconnect attempts are delayed exponentially until a new connection
is made
+         * or the maximum number of attempts is exceeded.  Using an exponential back-off
can
+         * reduce CPU overhead but can also lead to a longer time to reconnect to a service
that
+         * is known to have short drop outs.
+         *
+         * @param useExponentialBackOff
+         *     When true it indicates that the delay between reconnect attempts grows exponentially.
+         */
         void setUseExponentialBackOff(bool useExponentialBackOff);
 
+        /**
+         * Returns true if successive attempts to reconnect to a discovered service are delayed
+         * by an exponentially growing time factor.
+         *
+         * @returns whether exponential back-off is enabled.
+         */
         bool isUseExponentialBackOff() const;
 
+        /**
+         * Sets the discovery group that this agent is assigned.  The default value for this
+         * group is "default".
+         *
+         * @param group
+         *      The assigned group for the discovery agent.
+         */
         void setGroup(const std::string& group);
 
+        /**
+         * Returns the assigned group for this discovery agent.
+         *
+         * @returns the assigned group for this discovery agent.
+         */
         std::string getGroup() const;
 
     protected:
 
         /**
          * Default implementation of the DiscoveryAgent's background worker thread processing.
+         *
+         * In general there is no need for an agent to override this method, however some
agents
+         * may require special handling of their discovery mechanisms so it is allowable
for this
+         * method to be overridden.  Implementors of this method must ensure that the run
method
+         * will return quickly once the started value becomes false or the Thread is interrupted.
          */
         virtual void run();
 
@@ -157,13 +232,29 @@ namespace discovery {
     protected:
 
         /**
-         * The real agent will implement this method to perform any necessary resource allocation
+         * The real agent class must implement this method to perform any necessary resource
allocation
          * prior to the completion of the start call.
          */
         virtual void doStart() = 0;
 
+        /**
+         * The real agent class must implement this method to perform any necessary resource
cleanup
+         * prior to the completion of the stop call.
+         */
         virtual void doStop() = 0;
+
+        /**
+         * Optional method that allows the agent to perform an advertisement of this clients
+         * service.  Not all agents can do this so this method should be a no-op if this
is
+         * not supported.
+         */
         virtual void doAdvertizeSelf() = 0;
+
+        /**
+         * Performs the actual discovery operation for this agent.  This method is called
in the
+         * worker thread context of the AbstractDiscoveryAgent and should not block forever.
 The
+         * method will be called repeatedly to allow the agent to continually probe for new
services.
+         */
         virtual void doDiscovery() = 0;
 
     private:

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgentFactory.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgentFactory.cpp
b/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgentFactory.cpp
new file mode 100644
index 0000000..fa1d61a
--- /dev/null
+++ b/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgentFactory.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#include <activemq/transport/discovery/AbstractDiscoveryAgentFactory.h>
+
+#include <activemq/util/URISupport.h>
+#include <activemq/exceptions/ActiveMQException.h>
+
+#include <decaf/lang/Boolean.h>
+#include <decaf/lang/Integer.h>
+#include <decaf/lang/Long.h>
+
+using namespace decaf;
+using namespace decaf::net;
+using namespace decaf::util;
+using namespace decaf::lang;
+using namespace activemq;
+using namespace activemq::util;
+using namespace activemq::exceptions;
+using namespace activemq::transport;
+using namespace activemq::transport::discovery;
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractDiscoveryAgentFactory::~AbstractDiscoveryAgentFactory() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Pointer<DiscoveryAgent> AbstractDiscoveryAgentFactory::createAgent(const URI& agentURI)
{
+
+    try {
+
+        Pointer<AbstractDiscoveryAgent> agent = this->doCreateAgent();
+
+        Properties options = URISupport::parseParameters(agentURI);
+        doConfigureAgent(agent, options);
+
+        return agent;
+    }
+    AMQ_CATCH_RETHROW(ActiveMQException)
+    AMQ_CATCH_EXCEPTION_CONVERT(Exception, ActiveMQException)
+    AMQ_CATCHALL_THROW(ActiveMQException)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractDiscoveryAgentFactory::doConfigureAgent(Pointer<AbstractDiscoveryAgent>
agent, const Properties& options) {
+
+    try {
+
+        agent->setKeepAliveInterval(
+            Long::parseLong(options.getProperty("keepAliveInterval", "500")));
+        agent->setMaxReconnectDelay(
+            Long::parseLong(options.getProperty("maxReconnectDelay", "30000")));
+        agent->setUseExponentialBackOff(
+            Boolean::parseBoolean(options.getProperty("useExponentialBackOff", "true")));
+        agent->setBackOffMultiplier(
+            Long::parseLong(options.getProperty("backOffMultiplier", "2")));
+        agent->setMaxReconnectAttempts(
+            Integer::parseInt(options.getProperty("maxReconnectAttempts", "-1")));
+        agent->setInitialReconnectDelay(
+            Long::parseLong(options.getProperty("initialReconnectDelay", "10")));
+        agent->setGroup(options.getProperty("group", "default"));
+        agent->setGroup(options.getProperty("service", ""));
+    }
+    AMQ_CATCH_RETHROW(ActiveMQException)
+    AMQ_CATCH_EXCEPTION_CONVERT(Exception, ActiveMQException)
+    AMQ_CATCHALL_THROW(ActiveMQException)
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgentFactory.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgentFactory.h
b/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgentFactory.h
new file mode 100644
index 0000000..1582d3c
--- /dev/null
+++ b/activemq-cpp/src/main/activemq/transport/discovery/AbstractDiscoveryAgentFactory.h
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+#ifndef _ACTIVEMQ_TRANSPORT_DISCOVERY_ABSTRACTDISCOVERYAGENTFACTORY_H_
+#define _ACTIVEMQ_TRANSPORT_DISCOVERY_ABSTRACTDISCOVERYAGENTFACTORY_H_
+
+#include <activemq/util/Config.h>
+
+#include <decaf/lang/Pointer.h>
+#include <decaf/util/Properties.h>
+#include <decaf/net/URI.h>
+
+#include <activemq/transport/discovery/DiscoveryAgentFactory.h>
+#include <activemq/transport/discovery/AbstractDiscoveryAgent.h>
+
+namespace activemq {
+namespace transport {
+namespace discovery {
+
+    class AMQCPP_API AbstractDiscoveryAgentFactory : public DiscoveryAgentFactory {
+    public:
+
+        virtual ~AbstractDiscoveryAgentFactory();
+
+        /**
+         * Provides the implementation of the createAgent method, subclasses should implement
the
+         * doCreateAgent method to do the actual agent creation and override the doConfigureAgent
if
+         * they have additional URI options that need to be applied before returning the
newly
+         * created agent instance.
+         *
+         * @param agentURI
+         *      The URI that describes the agent and any requested configuration changes.
+         *
+         * @returns a new DiscoveryAgent instance with all URI options applied.
+         */
+        virtual decaf::lang::Pointer<DiscoveryAgent> createAgent(const decaf::net::URI&
agentURI);
+
+    protected:
+
+        /**
+         * Subclasses are required to implement this method and return the correct Agent
instance.
+         *
+         * After this method is called by createAgent the configuration method will be invoked
to
+         * allow the URI options to be applied.
+         *
+         * @returns a Pointer to the newly created discovery agent instance.
+         *
+         * @throws ActiveMQException if an error occurs while creating the agent.
+         */
+        virtual decaf::lang::Pointer<AbstractDiscoveryAgent> doCreateAgent() = 0;
+
+    protected:
+
+        /**
+         * Called from createAgent after the new agent instance has been created.  The default
+         * implementation of this method will configure all the known AbstractDiscoveryAgent
+         * options using the URI options given.  Subclasses can override this method to apply
+         * addition URI options specific to the agent type being created but should also
call
+         * this method to ensure that all options are applied.
+         *
+         * @param agent
+         *      The AbstractDiscoveryAgent instance that is to be configured.
+         * @param options
+         *      The Properties object that contians all agent options parsed from the URI.
+         *
+         * @throws ActiveMQException if an error occurs while applying the options.
+         */
+        virtual void doConfigureAgent(decaf::lang::Pointer<AbstractDiscoveryAgent>
agent,
+                                      const decaf::util::Properties& options);
+
+    };
+
+}}}
+
+#endif /* _ACTIVEMQ_TRANSPORT_DISCOVERY_ABSTRACTDISCOVERYAGENTFACTORY_H_ */

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/test/Makefile.am
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/Makefile.am b/activemq-cpp/src/test/Makefile.am
index aba643f..206ba47 100644
--- a/activemq-cpp/src/test/Makefile.am
+++ b/activemq-cpp/src/test/Makefile.am
@@ -55,6 +55,8 @@ cc_sources = \
     activemq/transport/IOTransportTest.cpp \
     activemq/transport/TransportRegistryTest.cpp \
     activemq/transport/correlator/ResponseCorrelatorTest.cpp \
+    activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.cpp \
+    activemq/transport/discovery/AbstractDiscoveryAgentTest.cpp \
     activemq/transport/discovery/DiscoveryAgentRegistryTest.cpp \
     activemq/transport/discovery/DiscoveryTransportFactoryTest.cpp \
     activemq/transport/failover/FailoverTransportTest.cpp \
@@ -307,6 +309,8 @@ h_sources = \
     activemq/transport/IOTransportTest.h \
     activemq/transport/TransportRegistryTest.h \
     activemq/transport/correlator/ResponseCorrelatorTest.h \
+    activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.h \
+    activemq/transport/discovery/AbstractDiscoveryAgentTest.h \
     activemq/transport/discovery/DiscoveryAgentRegistryTest.h \
     activemq/transport/discovery/DiscoveryTransportFactoryTest.h \
     activemq/transport/failover/FailoverTransportTest.h \

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.cpp
b/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.cpp
new file mode 100644
index 0000000..4435b2e
--- /dev/null
+++ b/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.cpp
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#include "AbstractDiscoveryAgentFactoryTest.h"
+
+#include <activemq/transport/discovery/AbstractDiscoveryAgent.h>
+#include <activemq/transport/discovery/AbstractDiscoveryAgentFactory.h>
+#include <activemq/transport/discovery/DiscoveryAgentRegistry.h>
+
+#include <decaf/net/URI.h>
+
+using namespace activemq;
+using namespace activemq::transport;
+using namespace activemq::transport::discovery;
+using namespace decaf;
+using namespace decaf::util;
+using namespace decaf::net;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class MockDiscoveryAgent : public AbstractDiscoveryAgent {
+    private:
+
+        bool reported;
+
+    public:
+
+        virtual ~MockDiscoveryAgent() {}
+
+        virtual std::string toString() const { return "MockDiscoveryAgent"; }
+
+    protected:
+
+        virtual void doStart() {
+            reported = false;
+        }
+
+        virtual void doStop() {}
+
+        virtual void doAdvertizeSelf() {}
+
+        virtual void doDiscovery() {
+            try {
+                if (!reported) {
+                    Thread::sleep(1000);
+                    processLiveService("dummy", "mock://localhost");
+                    reported = true;
+                } else {
+                    Thread::sleep(500);
+                }
+            } catch (InterruptedException& ex) {
+            }
+        }
+    };
+
+    class MockDiscoveryAgentFactory : public AbstractDiscoveryAgentFactory {
+    public:
+
+        virtual ~MockDiscoveryAgentFactory() {}
+
+        virtual decaf::lang::Pointer<AbstractDiscoveryAgent> doCreateAgent() {
+            return Pointer<AbstractDiscoveryAgent>(new MockDiscoveryAgent);
+        }
+
+    };
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractDiscoveryAgentFactoryTest::AbstractDiscoveryAgentFactoryTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractDiscoveryAgentFactoryTest::~AbstractDiscoveryAgentFactoryTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractDiscoveryAgentFactoryTest::test() {
+
+    DiscoveryAgentRegistry& registry = DiscoveryAgentRegistry::getInstance();
+    registry.registerFactory("mock", new MockDiscoveryAgentFactory);
+
+    CPPUNIT_ASSERT_EQUAL(1, (int) registry.getAgentNames().size());
+
+    DiscoveryAgentFactory* factory = registry.findFactory("mock");
+    CPPUNIT_ASSERT(factory != NULL);
+
+    Pointer<DiscoveryAgent> agent(factory->createAgent(URI("mock://default")));
+    CPPUNIT_ASSERT(agent != NULL);
+
+    Pointer<MockDiscoveryAgent> mock = agent.dynamicCast<MockDiscoveryAgent>();
+    CPPUNIT_ASSERT(mock != NULL);
+
+    registry.unregisterAllFactories();
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.h
b/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.h
new file mode 100644
index 0000000..a69eeee
--- /dev/null
+++ b/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef _ACTIVEMQ_TRANSPORT_DISCOVERY_ABSTRACTDISCOVERYAGENTFACTORYTEST_H_
+#define _ACTIVEMQ_TRANSPORT_DISCOVERY_ABSTRACTDISCOVERYAGENTFACTORYTEST_H_
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace activemq {
+namespace transport {
+namespace discovery {
+
+    class AbstractDiscoveryAgentFactoryTest : public CppUnit::TestFixture {
+
+        CPPUNIT_TEST_SUITE(AbstractDiscoveryAgentFactoryTest);
+        CPPUNIT_TEST( test );
+        CPPUNIT_TEST_SUITE_END();
+
+    public:
+
+        AbstractDiscoveryAgentFactoryTest();
+        virtual ~AbstractDiscoveryAgentFactoryTest();
+
+        void test();
+
+    };
+
+}}}
+
+#endif /* _ACTIVEMQ_TRANSPORT_DISCOVERY_ABSTRACTDISCOVERYAGENTFACTORYTEST_H_ */

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentTest.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentTest.cpp
b/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentTest.cpp
new file mode 100644
index 0000000..7595bd5
--- /dev/null
+++ b/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentTest.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+#include "AbstractDiscoveryAgentTest.h"
+
+#include <activemq/transport/discovery/DiscoveryListener.h>
+#include <activemq/transport/discovery/AbstractDiscoveryAgent.h>
+#include <activemq/transport/discovery/DiscoveryAgentFactory.h>
+#include <activemq/transport/discovery/DiscoveryAgentRegistry.h>
+
+#include <decaf/net/URI.h>
+#include <decaf/util/concurrent/CountDownLatch.h>
+
+using namespace activemq;
+using namespace activemq::transport;
+using namespace activemq::transport::discovery;
+using namespace decaf;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+using namespace decaf::net;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class MockDiscoveryAgent : public AbstractDiscoveryAgent {
+    private:
+
+        bool reported;
+
+    public:
+
+        virtual ~MockDiscoveryAgent() {}
+
+        virtual std::string toString() const { return "MockDiscoveryAgent"; }
+
+    protected:
+
+        virtual void doStart() {
+            reported = false;
+        }
+
+        virtual void doStop() {}
+
+        virtual void doAdvertizeSelf() {}
+
+        virtual void doDiscovery() {
+            try {
+                if (!reported) {
+                    Thread::sleep(1000);
+                    processLiveService("dummy", "mock://localhost");
+                    reported = true;
+                } else {
+                    Thread::sleep(500);
+                }
+            } catch (InterruptedException& ex) {
+            }
+        }
+
+    };
+
+    class MockDiscoveryAgentFactory : public DiscoveryAgentFactory {
+    public:
+
+        virtual ~MockDiscoveryAgentFactory() {}
+
+        virtual decaf::lang::Pointer<DiscoveryAgent> createAgent(const decaf::net::URI&
agentURI) {
+            return Pointer<DiscoveryAgent>(new MockDiscoveryAgent);
+        }
+
+    };
+
+    class MockDiscoveryListener : public DiscoveryListener {
+    public:
+
+        CountDownLatch* added;
+        CountDownLatch* removed;
+
+    public:
+
+        MockDiscoveryListener(CountDownLatch* added, CountDownLatch* removed) :
+            DiscoveryListener(), added(added), removed(removed) {}
+        virtual ~MockDiscoveryListener() {}
+
+        virtual void onServiceAdd(const activemq::commands::DiscoveryEvent* event) {
+            added->countDown();
+        }
+
+        virtual void onServiceRemove(const activemq::commands::DiscoveryEvent* event) {
+            removed->countDown();
+        }
+    };
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractDiscoveryAgentTest::AbstractDiscoveryAgentTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractDiscoveryAgentTest::~AbstractDiscoveryAgentTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractDiscoveryAgentTest::test() {
+
+    CountDownLatch added(1);
+    CountDownLatch removed(1);
+
+    MockDiscoveryListener listener(&added, &removed);
+
+    DiscoveryAgentRegistry& registry = DiscoveryAgentRegistry::getInstance();
+    registry.registerFactory("mock", new MockDiscoveryAgentFactory);
+
+    CPPUNIT_ASSERT_EQUAL(1, (int) registry.getAgentNames().size());
+
+    DiscoveryAgentFactory* factory = registry.findFactory("mock");
+    CPPUNIT_ASSERT(factory != NULL);
+
+    Pointer<DiscoveryAgent> agent(factory->createAgent(URI("mock://default")));
+    CPPUNIT_ASSERT(agent != NULL);
+
+    agent->setDiscoveryListener(&listener);
+    agent->start();
+
+    CPPUNIT_ASSERT_MESSAGE("Should have discovered by now", added.await(60000));
+    CPPUNIT_ASSERT_MESSAGE("Should have timed out by now", removed.await(60000));
+
+    registry.unregisterAllFactories();
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentTest.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentTest.h
b/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentTest.h
new file mode 100644
index 0000000..e7d681d
--- /dev/null
+++ b/activemq-cpp/src/test/activemq/transport/discovery/AbstractDiscoveryAgentTest.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef _ACTIVEMQ_TRANSPORT_DISCOVERY_ABSTRACTDISCOVERYAGENTTEST_H_
+#define _ACTIVEMQ_TRANSPORT_DISCOVERY_ABSTRACTDISCOVERYAGENTTEST_H_
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace activemq {
+namespace transport {
+namespace discovery {
+
+    class AbstractDiscoveryAgentTest : public CppUnit::TestFixture {
+
+        CPPUNIT_TEST_SUITE(AbstractDiscoveryAgentTest);
+        CPPUNIT_TEST( test );
+        CPPUNIT_TEST_SUITE_END();
+
+    public:
+
+        AbstractDiscoveryAgentTest();
+        virtual ~AbstractDiscoveryAgentTest();
+
+        void test();
+
+    };
+
+}}}
+
+#endif /* _ACTIVEMQ_TRANSPORT_DISCOVERY_ABSTRACTDISCOVERYAGENTTEST_H_ */

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/9c8ab032/activemq-cpp/src/test/testRegistry.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/testRegistry.cpp b/activemq-cpp/src/test/testRegistry.cpp
index f33e8ce..2c30823 100644
--- a/activemq-cpp/src/test/testRegistry.cpp
+++ b/activemq-cpp/src/test/testRegistry.cpp
@@ -125,6 +125,10 @@ CPPUNIT_TEST_SUITE_REGISTRATION( activemq::transport::inactivity::InactivityMoni
 CPPUNIT_TEST_SUITE_REGISTRATION( activemq::transport::discovery::DiscoveryAgentRegistryTest
);
 #include <activemq/transport/discovery/DiscoveryTransportFactoryTest.h>
 CPPUNIT_TEST_SUITE_REGISTRATION( activemq::transport::discovery::DiscoveryTransportFactoryTest
);
+#include <activemq/transport/discovery/AbstractDiscoveryAgentTest.h>
+CPPUNIT_TEST_SUITE_REGISTRATION( activemq::transport::discovery::AbstractDiscoveryAgentTest
);
+#include <activemq/transport/discovery/AbstractDiscoveryAgentFactoryTest.h>
+CPPUNIT_TEST_SUITE_REGISTRATION( activemq::transport::discovery::AbstractDiscoveryAgentFactoryTest
);
 
 #include <activemq/transport/TransportRegistryTest.h>
 CPPUNIT_TEST_SUITE_REGISTRATION( activemq::transport::TransportRegistryTest );


Mime
View raw message