[asterisk-scf-commits] asterisk-scf/integration/ice-util-cpp.git branch "collocated-icestorm" created.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Tue May 17 08:19:06 CDT 2011
branch "collocated-icestorm" has been created
at c857c099bf0825ee10e637b0ba5a6860ba0289d2 (commit)
- Log -----------------------------------------------------------------
commit c857c099bf0825ee10e637b0ba5a6860ba0289d2
Author: Joshua Colp <jcolp at digium.com>
Date: Tue May 17 10:20:02 2011 -0300
Make the collocated icestorm available to all.
diff --git a/include/AsteriskSCF/CollocatedIceStorm/CollocatedIceStorm.h b/include/AsteriskSCF/CollocatedIceStorm/CollocatedIceStorm.h
new file mode 100644
index 0000000..f135838
--- /dev/null
+++ b/include/AsteriskSCF/CollocatedIceStorm/CollocatedIceStorm.h
@@ -0,0 +1,57 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+#pragma once
+
+#include <IceUtil/DynamicLibrary.h>
+#include <Ice/Service.h>
+#include <IceBox/IceBox.h>
+#include <Ice/Ice.h>
+#include <IceStorm/IceStorm.h>
+#include <string>
+
+namespace AsteriskSCF
+{
+namespace CollocatedIceStorm
+{
+
+/**
+ * A helper class that instantiates IceStorm in-process, removing the need to launch
+ * a separate process to access IceStorm services.
+ */
+
+class CollocatedIceStorm : public IceUtil::Shared
+{
+public:
+ CollocatedIceStorm(const std::string&, const Ice::PropertiesPtr&);
+ ~CollocatedIceStorm();
+
+ /**
+ * "nice" applications should explictly call stop !
+ */
+ void stop();
+
+private:
+ IceUtilInternal::DynamicLibraryPtr mLibrary;
+ IceBox::ServicePtr mService;
+ Ice::CommunicatorPtr mCommunicator;
+ bool mStopped;
+};
+
+typedef IceUtil::Handle<CollocatedIceStorm> CollocatedIceStormPtr;
+
+} /* end of CollocatedIceStorm */
+} /* end of AsteriskSCF */
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6bd28d1..79698d6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -32,6 +32,8 @@ asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/ThreadPool/T
asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/ThreadPool/WorkerThread.h)
asterisk_scf_component_add_file(ice-util-cpp ThreadPool/ThreadPool.cpp)
asterisk_scf_component_add_file(ice-util-cpp ThreadPool/WorkerThread.cpp)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/CollocatedIceStorm/CollocatedIceStorm.h)
+asterisk_scf_component_add_file(ice-util-cpp CollocatedIceStorm/CollocatedIceStorm.cpp)
#
# Note, strictly speaking this isn't for component development, but as it is part of this
diff --git a/src/CollocatedIceStorm/CollocatedIceStorm.cpp b/src/CollocatedIceStorm/CollocatedIceStorm.cpp
new file mode 100644
index 0000000..8903918
--- /dev/null
+++ b/src/CollocatedIceStorm/CollocatedIceStorm.cpp
@@ -0,0 +1,88 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+#include <Ice/Ice.h>
+#include <IceStorm/IceStorm.h>
+#include <assert.h>
+#include <algorithm>
+
+#include <AsteriskSCF/CollocatedIceStorm/CollocatedIceStorm.h>
+
+using namespace AsteriskSCF::CollocatedIceStorm;
+
+//
+// The idea behind this class is that it needs to access the entry point that IceBox would
+// have used and then invoke the methods that are needed to start and stop the IceStorm
+// service.
+//
+typedef IceBox::Service* (*FACTORY)(Ice::CommunicatorPtr);
+
+CollocatedIceStorm::CollocatedIceStorm(const std::string& namePrefix, const Ice::PropertiesPtr& properties) :
+ mStopped(false)
+{
+ //
+ // We create our own communicator to avoid issues with call order on shutdown.
+ //
+ Ice::InitializationData initData;
+ initData.properties = properties;
+ mCommunicator = Ice::initialize(initData);
+
+ std::string loadString = mCommunicator->getProperties()->getPropertyWithDefault("IceStorm.EntryPoint", "IceStormService:createIceStorm");
+
+ mLibrary = new IceUtilInternal::DynamicLibrary;
+ IceUtilInternal::DynamicLibrary::symbol_type entry = mLibrary->loadEntryPoint(loadString);
+ if(entry == 0)
+ {
+ throw mLibrary->getErrorMessage();
+ }
+ FACTORY factory = (FACTORY)entry;
+ mService = factory(mCommunicator);
+ assert(mService != 0);
+ Ice::StringSeq options;
+ mService->start(namePrefix, mCommunicator, options);
+}
+
+CollocatedIceStorm::~CollocatedIceStorm()
+{
+ if(!mStopped)
+ {
+ try
+ {
+ stop();
+ mCommunicator->destroy();
+ }
+ catch(...)
+ {
+ }
+ }
+}
+
+void CollocatedIceStorm::stop()
+{
+ //
+ // NOTE: there isn't any mutex protection here. It can be added later if needed, but at the moment multiple threads
+ // do not have access to this object instance.
+ //
+ if(!mStopped)
+ {
+ if(mService)
+ {
+ mService->stop();
+ }
+ mCommunicator->shutdown();
+ mCommunicator->waitForShutdown();
+ mStopped = true;
+ }
+}
commit f7cba542d05950d203efac40d3e96bcd1ba51734
Author: Brent Eagles <beagles at digium.com>
Date: Sun May 15 15:16:27 2011 -0230
Added several utility classes from the briding service and reorganized
directories and header files. Header files are now organized by functional
area and the various utilities are gathered under a single utility library.
diff --git a/AmiCollector/CMakeLists.txt b/AmiCollector/CMakeLists.txt
deleted file mode 100644
index 79b910f..0000000
--- a/AmiCollector/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-include_directories(include)
-
-asterisk_scf_component_init(ami-collector)
-asterisk_scf_component_add_file(ami-collector include/AsteriskSCF/AmiCollector.h)
-asterisk_scf_component_add_file(ami-collector include/AsteriskSCF/ResponseCollector.h)
-asterisk_scf_component_add_file(ami-collector src/AmiCollector.cpp)
-asterisk_scf_component_add_boost_libraries(ami-collector thread)
-asterisk_scf_component_build_library(ami-collector)
-
-# don't install the component. it's just there to make Visual Studio happy
-# _do_ install the header files
-asterisk_scf_headers_install(include)
-
-add_subdirectory(test)
diff --git a/AmiCollector/src/AmiCollector.cpp b/AmiCollector/src/AmiCollector.cpp
deleted file mode 100644
index c0244fe..0000000
--- a/AmiCollector/src/AmiCollector.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Asterisk SCF -- An open-source communications framework.
- *
- * Copyright (C) 2010, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk SCF project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE.txt file
- * at the top of the source tree.
- */
-
-#include <AsteriskSCF/AmiCollector.h>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 29baa66..bbaf307 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,9 +4,5 @@ if (integrated_build STREQUAL "true")
set(utils_dir ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
endif()
-add_subdirectory(SmartProxy)
-add_subdirectory(StateReplicator)
-add_subdirectory(AmiCollector)
-add_subdirectory(TestFixture)
-add_subdirectory(WorkQueue)
-add_subdirectory(ThreadPool)
+add_subdirectory(src)
+add_subdirectory(test)
diff --git a/SmartProxy/CMakeLists.txt b/SmartProxy/CMakeLists.txt
deleted file mode 100644
index c137a64..0000000
--- a/SmartProxy/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-include_directories(include)
-if(NOT logger_dir)
- message(FATAL_ERROR "The logger directory could not be found ${logger_dir}")
-endif()
-include_directories(${logger_dir}/include)
-include_directories(${API_INCLUDE_DIR})
-
-asterisk_scf_component_init(SmartProxy)
-asterisk_scf_component_add_file(SmartProxy include/AsteriskSCF/SmartProxy.h)
-asterisk_scf_component_add_file(SmartProxy src/SmartProxy.cpp)
-asterisk_scf_component_add_boost_libraries(SmartProxy core)
-asterisk_scf_component_build_library(SmartProxy)
-target_link_libraries(SmartProxy logging-client)
-
-# don't install the component. it's just there to make Visual Studio happy
-# _do_ install the header files
-asterisk_scf_headers_install(include)
diff --git a/StateReplicator/CMakeLists.txt b/StateReplicator/CMakeLists.txt
deleted file mode 100644
index 69bc146..0000000
--- a/StateReplicator/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-include_directories(include)
-
-asterisk_scf_component_init(StateReplicator)
-asterisk_scf_component_add_file(StateReplicator include/AsteriskSCF/StateReplicator.h)
-asterisk_scf_component_add_file(StateReplicator src/StateReplicator.cpp)
-asterisk_scf_component_add_boost_libraries(StateReplicator thread)
-asterisk_scf_component_build_library(StateReplicator)
-
-# don't install the component. it's just there to make Visual Studio happy
-# _do_ install the header files
-asterisk_scf_headers_install(include)
-
-add_subdirectory(test)
diff --git a/TestFixture/CMakeLists.txt b/TestFixture/CMakeLists.txt
deleted file mode 100644
index bf09c89..0000000
--- a/TestFixture/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-include_directories(include)
-
-asterisk_scf_component_init(testfixture)
-asterisk_scf_component_add_file(testfixture include/AsteriskSCF/IceBoxBoostTest.h)
-asterisk_scf_component_add_file(testfixture src/TestFixture.cpp)
-asterisk_scf_component_add_boost_libraries(testfixture unit_test_framework)
-asterisk_scf_component_build_icebox(testfixture)
-
-# don't install the component. it's just there to make Visual Studio happy
-# _do_ install the header files
-asterisk_scf_headers_install(include)
diff --git a/ThreadPool/CMakeLists.txt b/ThreadPool/CMakeLists.txt
deleted file mode 100644
index b1a0931..0000000
--- a/ThreadPool/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Asterisk Scalable Communications Framework
-#
-# Copyright (C) 2011 -- Digium, Inc.
-#
-# All rights reserved.
-#
-
-add_subdirectory(src)
-add_subdirectory(test)
diff --git a/WorkQueue/CMakeLists.txt b/WorkQueue/CMakeLists.txt
deleted file mode 100644
index b1a0931..0000000
--- a/WorkQueue/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Asterisk Scalable Communications Framework
-#
-# Copyright (C) 2011 -- Digium, Inc.
-#
-# All rights reserved.
-#
-
-add_subdirectory(src)
-add_subdirectory(test)
diff --git a/config/IceUtilCppTests.conf b/config/IceUtilCppTests.conf
new file mode 100644
index 0000000..745d32f
--- /dev/null
+++ b/config/IceUtilCppTests.conf
@@ -0,0 +1,20 @@
+################################################################################
+# Configuration file for use with the bridging component's test driver.
+#
+#
+# General configuration
+#
+# We turn off all collocation optimization by default to avoid issues with any services
+# that might have trouble due to AMI/AMD usage.
+#
+Ice.Default.CollocationOptimized=0
+
+#
+# We use a single file for configuration.
+#
+IceBox.InheritProperties=1
+IceBox.ServiceManager.Endpoints=default -p 56000
+IceBox.ServiceManager.ThreadPool.Size=4
+IceBoxManager.Proxy=IceBox/ServiceManager:default -p 56000
+
+IceBox.Service.ProxyHelper=ascf-ice-util-cpp-tests:create
diff --git a/AmiCollector/include/AsteriskSCF/AmiCollector.h b/include/AsteriskSCF/Async/AmiCollector.h
similarity index 96%
rename from AmiCollector/include/AsteriskSCF/AmiCollector.h
rename to include/AsteriskSCF/Async/AmiCollector.h
index cd703c3..3bfc276 100644
--- a/AmiCollector/include/AsteriskSCF/AmiCollector.h
+++ b/include/AsteriskSCF/Async/AmiCollector.h
@@ -22,13 +22,12 @@
#include <IceUtil/Handle.h>
#include <IceUtil/Shared.h>
-#include <AsteriskSCF/ResponseCollector.h>
+#include <AsteriskSCF/Async/ResponseCollector.h>
namespace AsteriskSCF
{
-namespace IceUtil
+namespace Async
{
-
/**
* Collects the results for multiple asynchronous responses. While the response
* counting logic is properly locked and thread safe, it is incumbent upon the
@@ -122,5 +121,5 @@ private:
}
};
-} // IceUtil
-} // AsteriskSCF
+} /* End of namespace Async */
+} /* End of namespace AsteriskSCF */
diff --git a/AmiCollector/include/AsteriskSCF/ResponseCollector.h b/include/AsteriskSCF/Async/ResponseCollector.h
similarity index 97%
rename from AmiCollector/include/AsteriskSCF/ResponseCollector.h
rename to include/AsteriskSCF/Async/ResponseCollector.h
index de2e011..d55f504 100644
--- a/AmiCollector/include/AsteriskSCF/ResponseCollector.h
+++ b/include/AsteriskSCF/Async/ResponseCollector.h
@@ -21,6 +21,8 @@
namespace AsteriskSCF
{
+namespace Async
+{
class TooManyInvocations : public std::exception
{
@@ -132,4 +134,5 @@ private:
}
};
-} // AsteriskSCF
+} /* End of namespace Async */
+} /* End of namespace AsteriskSCF */
diff --git a/include/AsteriskSCF/Discovery/LocatorRegistrationWrapper.h b/include/AsteriskSCF/Discovery/LocatorRegistrationWrapper.h
new file mode 100644
index 0000000..ca8e81a
--- /dev/null
+++ b/include/AsteriskSCF/Discovery/LocatorRegistrationWrapper.h
@@ -0,0 +1,177 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010-2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+#pragma once
+
+#include <Ice/Ice.h>
+#include <IceUtil/Thread.h>
+#include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
+#include <string>
+
+namespace AsteriskSCF
+{
+namespace Discovery
+{
+
+/**
+ *
+ * Helper template for services that need to be registered with the locator service. If the service may not
+ * immediately available, the RegisterThread can be used to continue to try and register the service.
+ *
+ * TODO: It might be handy to add some "termination conditions" so it doesn't simply wait forever.
+ *
+ **/
+template <class T>
+class LocatorRegistrationWrapper : public IceUtil::Shared
+{
+public:
+
+ /**
+ * Normally, I avoid default args, but you can't really implement one constructor in terms of another
+ * so it's less maintenance overhead to have the single constructor with the defaults.
+ **/
+ LocatorRegistrationWrapper(const Ice::CommunicatorPtr& communicator, const std::string& proxyString,
+ const T& service, const std::string& name,
+ const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr& params,
+ const std::string& comparatorGUID = "") :
+ mCommunicator(communicator),
+ mProxyString(proxyString),
+ mService(service),
+ mName(name),
+ mParameters(params),
+ mComparatorGUID(comparatorGUID)
+ {
+ }
+
+ /**
+ * The main registration function. There is *no* exception handling, so the caller must be prepared
+ * to handle whatever might be thrown.
+ **/
+ bool registerService()
+ {
+ AsteriskSCF::Core::Discovery::V1::ServiceLocatorManagementPrx management =
+ AsteriskSCF::Core::Discovery::V1::ServiceLocatorManagementPrx::checkedCast(
+ mCommunicator->stringToProxy(mProxyString));
+ if (management)
+ {
+ IceUtil::Mutex::Lock lock(mLock);
+ mServiceManagement =
+ AsteriskSCF::Core::Discovery::V1::ServiceManagementPrx::uncheckedCast(
+ management->addService(mService, mName));
+ if (mServiceManagement)
+ {
+ mServiceManagement->addLocatorParams(mParameters, mComparatorGUID);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Unregister! Note that the destructor for this object does not automatically unregister. This is
+ * because this class is intended as a helper, not an RAII type of object to manage the registration.
+ * It would be easy enough for a developer to derive from an instance of this class and add that
+ * functionality if desired.
+ **/
+ void unregister()
+ {
+ {
+ IceUtil::Mutex::Lock lock(mLock);
+ if (!mServiceManagement)
+ {
+ return;
+ }
+ }
+ mServiceManagement->unregister();
+ }
+
+private:
+
+ //
+ // This template doesn't use boost locking simply because it already has a physical dependency
+ // to Ice runtime, so avoiding adding a second seemed reasonable.
+ //
+ IceUtil::Mutex mLock;
+ Ice::CommunicatorPtr mCommunicator;
+ std::string mProxyString;
+ T mService;
+ std::string mName;
+ AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr mParameters;
+ AsteriskSCF::Core::Discovery::V1::ServiceManagementPrx mServiceManagement;
+ std::string mComparatorGUID;
+};
+
+/**
+* This thread takes care of registering the registration wrapper instance if the service discovery components are
+ * unavailable during startup.
+ **/
+template <class T>
+class RegisterThread : public IceUtil::Thread
+{
+public:
+ RegisterThread(const IceUtil::Handle<LocatorRegistrationWrapper<T> >& registration,
+ const IceUtil::Time& retryInterval) :
+ mRegistration(registration),
+ mRetryInterval(retryInterval),
+ mStopped(false)
+ {
+ }
+
+ RegisterThread(const IceUtil::Handle<LocatorRegistrationWrapper<T> >& registration) :
+ mRegistration(registration),
+ mRetryInterval(IceUtil::Time::seconds(15)),
+ mStopped(false)
+ {
+ }
+
+ void run()
+ {
+ bool result = false;
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(mMonitor);
+ do
+ {
+ mMonitor.timedWait(mRetryInterval);
+ if(mStopped)
+ {
+ break;
+ }
+ try
+ {
+ result = mRegistration->registerService();
+ }
+ catch(const Ice::Exception&)
+ {
+ }
+ }
+ while(result == false);
+ }
+
+ void stop()
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(mMonitor);
+ mStopped = true;
+ mMonitor.notify();
+ }
+
+private:
+ IceUtil::Monitor<IceUtil::Mutex> mMonitor;
+ IceUtil::Handle<LocatorRegistrationWrapper<T> > mRegistration;
+ IceUtil::Time mRetryInterval;
+ bool mStopped;
+};
+
+} /* End of namespace Discovery */
+
+} /* End of namespace AsteriskSCF */
diff --git a/SmartProxy/include/AsteriskSCF/SmartProxy.h b/include/AsteriskSCF/Discovery/SmartProxy.h
similarity index 99%
rename from SmartProxy/include/AsteriskSCF/SmartProxy.h
rename to include/AsteriskSCF/Discovery/SmartProxy.h
index e2c691a..68a781c 100644
--- a/SmartProxy/include/AsteriskSCF/SmartProxy.h
+++ b/include/AsteriskSCF/Discovery/SmartProxy.h
@@ -20,12 +20,11 @@
#include <Ice/Ice.h>
#include <IceUtil/Mutex.h>
#include <AsteriskSCF/logger.h>
-
#include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
namespace AsteriskSCF
{
-namespace SmartProxy
+namespace Discovery
{
/**
@@ -159,7 +158,7 @@ public:
(*mLogger)(Error) << "Lookup failed";
}
- if (mProxy == 0)
+ if (!mProxy)
{
(*mLogger)(Error) << "Unable to locate " << mLocatorParams->category;
}
diff --git a/include/AsteriskSCF/Helpers/PropertyHelper.h b/include/AsteriskSCF/Helpers/PropertyHelper.h
new file mode 100644
index 0000000..b6579b8
--- /dev/null
+++ b/include/AsteriskSCF/Helpers/PropertyHelper.h
@@ -0,0 +1,181 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+#pragma once
+
+#include <Ice/Properties.h>
+#include <string>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+namespace AsteriskSCF
+{
+
+/**
+ *
+ * A very simple helper function template that encapsulates a common pattern when doing property validation when
+ * initializing Ice clients and servers. It goes one step further that the xWithDefault variants of property "get"
+ * methods by setting the property if is not otherwise set. Why do this? It can be handy if there is a convenient spot
+ * in your code to check a bunch of properties that you KNOW are going to be needed because of implementation details
+ * and you do not want to have to use the xWithDefault variants throughout your code. Note that this *DOES NOT* override
+ * any properties if they already exist.
+ *
+ **/
+inline std::string propGetSet(const Ice::PropertiesPtr& p, const std::string& propertyName, const std::string& value)
+{
+ std::string result = p->getPropertyWithDefault(propertyName, value);
+ p->setProperty(propertyName, result);
+ return result;
+}
+
+/**
+ *
+ * A generic helper template that can be specialized to help convert different types to std::strings
+ * for the StringVectorAsArgs template.
+ *
+ **/
+template <typename T>
+std::string convertToString(const T& t)
+{
+ return t;
+}
+
+/**
+ *
+ * StringVectorAsArgs is a class meant to be aggregated (but could also be derived from). It's intended use are for those
+ * situations where you are integrating code that requires the old C style an argument count and array of char* for
+ * passing arguments with code that has that data stored in string vector of some kind. NOTE: this is not thread
+ * safe! It would actually be pretty much impossible to truly make thread safe since argv() returns an array of char**
+ * that reference memory held by the instance.
+ *
+ **/
+class StringVectorAsArgs
+{
+public:
+
+ //
+ // Default and copy constructor.
+ //
+ StringVectorAsArgs()
+ {
+ std::vector<std::string> v;
+ mData.reset(new Data(v));
+ }
+
+ StringVectorAsArgs(const StringVectorAsArgs& props)
+ {
+ mData.reset(new Data(props.args()));
+ }
+
+ template <typename V>
+ explicit StringVectorAsArgs(const V& rhs)
+ {
+ std::vector<std::string> v;
+ copyV(rhs, v);
+ mData.reset(new Data(v));
+ }
+
+ /**
+ *
+ * Returns the argc equivalent of the vector.
+ *
+ * @returns the number or entries in argv.
+ *
+ **/
+ int argc()
+ {
+ return mData->mArgc;
+ }
+
+ /**
+ *
+ * Returns the argv equivalent of the vector (null terminated of course).
+ *
+ **/
+ char** argv()
+ {
+ return const_cast<char**>(static_cast<const char**>(&(mData->mArgv[0])));
+ }
+
+ /**
+ *
+ * Returns a copy of the original vector.
+ *
+ **/
+ std::vector<std::string> args() const
+ {
+ return mData->mArguments;
+ }
+
+ /**
+ *
+ * Copying is allowed and so should assignment.
+ *
+ */
+ StringVectorAsArgs& operator=(const StringVectorAsArgs& rhs)
+ {
+ if (this == &rhs)
+ {
+ return *this;
+ }
+ mData.reset(new Data(rhs.args()));
+
+ return *this;
+ }
+
+private:
+
+ struct Data
+ {
+ std::vector<std::string> mArguments;
+ int mArgc;
+ std::vector<const char*> mArgv;
+
+ Data(const std::vector<std::string>& v) :
+ mArguments(v)
+ {
+ for (std::vector<std::string>::const_iterator i = mArguments.begin(); i != mArguments.end(); ++i)
+ {
+ mArgv.push_back(i->c_str());
+ }
+ mArgv.push_back(static_cast<const char*>(0));
+ mArgc = static_cast<int>(mArgv.size()) - 1;
+ }
+ };
+
+ //
+ // Specializations exist for the most commonly used values of T. The general form allows for collections that a.)
+ // have a stl type iterator interface and b.) members can be directly assigned to std::string.
+ //
+ template <typename T>
+ void copyV(const T& src, std::vector<std::string>& dest)
+ {
+ typedef typename T::const_iterator iter;
+ for(iter i = src.begin(); i != src.end(); ++i)
+ {
+ dest.push_back(convertToString(*i));
+ }
+ }
+
+ boost::shared_ptr<Data> mData;
+};
+
+template<>
+inline void StringVectorAsArgs::copyV(const std::vector<std::string>& p, std::vector<std::string>& dest)
+{
+ dest = p;
+}
+
+};
diff --git a/include/AsteriskSCF/Helpers/ProxyHelper.h b/include/AsteriskSCF/Helpers/ProxyHelper.h
new file mode 100644
index 0000000..fdca98f
--- /dev/null
+++ b/include/AsteriskSCF/Helpers/ProxyHelper.h
@@ -0,0 +1,170 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include <assert.h>
+#include <Ice/Ice.h>
+
+//
+// GENERAL NOTE:
+// While these helpers can certainly be used in an application, they are most useful when writing
+// tests which usually include several repetitive instantiations of servants, proxies, etc.
+// Some of this becomes far less valuable when "auto" is used.
+//
+namespace AsteriskSCF
+{
+/**
+ *
+ * The getProxy call. NOTE: this function does not perform and release mode parameter checking (asserts for debug mode
+ * only), so the caller should do precondition validation if it at all possible for these arguments to be invalid.
+ *
+ *
+ * @param comm An Ice communicator instance.
+ * @param property The name of the property that contains the stringified proxy.
+ * @param typedParam A proxy handle of the required type.
+ *
+ * @returns An initialized proxy handle of the required type.
+ *
+ **/
+
+template <class T>
+T getProxy(const Ice::CommunicatorPtr& comm, const std::string& propertyName, T& typedParam, bool checked)
+{
+ assert(comm);
+ assert(!propertyName.empty());
+ Ice::ObjectPrx obj = comm->propertyToProxy(propertyName);
+ if (checked)
+ {
+ typedParam = T::checkedCast(obj);
+ }
+ else
+ {
+ typedParam = T::uncheckedCast(obj);
+ }
+ return typedParam;
+}
+
+template <class T>
+T getProxy(const Ice::CommunicatorPtr& comm, const std::string& propertyName, T& typedParam)
+{
+ return getProxy<T>(comm, propertyName, typedParam, true);
+}
+
+/**
+ *
+ * The addServant helper is a little like the getProxy helper. However, instead of pulling a proxy out
+ * of a communicator's configuration, this helper adds a servant to an object adapter and returns
+ * a proxy of the correct type.
+ *
+ **/
+template <class T>
+T addServant(const Ice::ObjectAdapterPtr& adapter, const Ice::ObjectPtr& servant, const Ice::Identity& t,
+ T& proxy)
+{
+ proxy = T::uncheckedCast(adapter->add(servant, t));
+ return proxy;
+}
+
+/**
+ * Overload for those folks that specify a string for an id.
+ **/
+template <class T>
+T addServant(const Ice::ObjectAdapterPtr& adapter, const Ice::ObjectPtr& servant, const std::string& s,
+ T& proxy)
+{
+ return addServant(adapter, servant, adapter->getCommunicator()->stringToIdentity(s), proxy);
+}
+
+//
+// The UUID variant is conspicuously absent for the moment. The signature of such a method would be very similar to
+// those above except it would be missing and ID of some kind. I'm concerned that it would get used accidentally.
+//
+
+/**
+ *
+ * A trivial little helper template that attempts to get a oneway proxy, but "rollsback" to the original
+ * proxy if the proxy's endpoints don't allow oneways. OF course, if the caller absolutely requires a
+ * request be over a oneway, then this template *SHOULD NOT* be used.
+ *
+ **/
+template <class PrxType>
+PrxType tryOneWay(const PrxType& orig)
+{
+ try
+ {
+ return PrxType::uncheckedCast(orig->ice_oneway());
+ }
+ catch (const Ice::NoEndpointException&)
+ {
+ }
+ return orig;
+}
+
+/**
+ *
+ * A predicate functor for testing on proxy identity. Handy when searching a collection with std::find().
+ *
+ **/
+template <class T>
+class IdentityComparePredicate : public std::unary_function<T, bool>
+{
+public:
+ IdentityComparePredicate(const T& example) :
+ mExample(example)
+ {
+ }
+
+ bool operator()(const T& toTest)
+ {
+ if (toTest == 0)
+ {
+ return mExample == 0;
+ }
+ if (mExample == 0)
+ {
+ return false;
+ }
+ return (mExample->ice_getIdentity() == toTest->ice_getIdentity());
+ }
+
+ template <class V>
+ bool operator()(const V& toTest)
+ {
+ if (toTest == 0)
+ {
+ return mExample == 0;
+ }
+ if (mExample == 0)
+ {
+ return false;
+ }
+ return (mExample->ice_getIdentity() == toTest->ice_getIdentity());
+ }
+private:
+ T mExample;
+};
+
+inline std::string objectId(const Ice::Current& current)
+{
+ if (current.adapter)
+ {
+ return current.adapter->getCommunicator()->identityToString(current.id);
+ }
+ return "(unknown)";
+}
+
+}; /* End of namespace AsteriskSCF */
diff --git a/include/AsteriskSCF/Helpers/Retry.h b/include/AsteriskSCF/Helpers/Retry.h
new file mode 100644
index 0000000..3d89bfb
--- /dev/null
+++ b/include/AsteriskSCF/Helpers/Retry.h
@@ -0,0 +1,82 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+#pragma once
+
+#include <Ice/Ice.h>
+#include <IceUtil/Thread.h>
+
+namespace AsteriskSCF
+{
+
+/**
+ *
+ * A simple helper class for implementing retry logic when dealing with remote procedure calls.
+ *
+ */
+class RetryPolicy
+{
+public:
+ /**
+ * The constructor for those that want to specify intervals in milliseconds.
+ */
+ RetryPolicy(size_t maxRetries, size_t intervalInMilliseconds) :
+ mMaxRetries(maxRetries),
+ mRetryInterval(IceUtil::Time::milliSeconds(intervalInMilliseconds)),
+ mCounter(0)
+ {
+ }
+
+ /**
+ * The constructor for those that want to specify intervals in whatever
+ * unit they like so long as it is converted to IceUtil::Time.
+ **/
+ RetryPolicy(size_t maxRetries, const IceUtil::Time& interval) :
+ mMaxRetries(maxRetries),
+ mRetryInterval(interval),
+ mCounter(0)
+ {
+ }
+
+ /**
+ * Check to see if we've exceed the specified number of retries.
+ *
+ * @returns true if there are attempts left.
+ **/
+ bool canRetry()
+ {
+ return mCounter < mMaxRetries;
+ }
+
+ /**
+ * Sleep for the configured interval.
+ *
+ * @returns true if there are attempts left.
+ **/
+ bool retry()
+ {
+ IceUtil::ThreadControl::sleep(mRetryInterval);
+ ++mCounter;
+ return canRetry();
+ }
+
+private:
+ size_t mMaxRetries;
+ IceUtil::Time mRetryInterval;
+ size_t mCounter;
+};
+
+
+} /* End of namespace AsteriskSCF */
diff --git a/include/AsteriskSCF/Listener/ListenerManager.h b/include/AsteriskSCF/Listener/ListenerManager.h
new file mode 100644
index 0000000..30eaa78
--- /dev/null
+++ b/include/AsteriskSCF/Listener/ListenerManager.h
@@ -0,0 +1,295 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+#pragma once
+
+#include <Ice/Ice.h>
+#include <IceStorm/IceStorm.h>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <string>
+#include <algorithm>
+#include <vector>
+
+#include <IceUtil/Thread.h>
+
+namespace AsteriskSCF
+{
+/**
+ *
+ * Helper template for classes that need to implement listener style interfaces and use IceStorm
+ * to distribute updates.
+ *
+ **/
+template <class T>
+class ListenerManagerT : public IceUtil::Shared
+{
+ typedef std::vector<T> ListenerSeq;
+ typename std::vector<T>::iterator ListenerIter;
+
+ /**
+ *
+ * The InitializationThread allows the ListenerManager instance to initialize asynchronously,
+ * avoiding startup order issues. Note that notifications that are forwarded before
+ * initialization occurs are lost (subscriptions are not).
+ *
+ **/
+ class InitializationThread : public IceUtil::Thread
+ {
+ public:
+ InitializationThread(const typename IceUtil::Handle<ListenerManagerT>& mgr,
+ const IceUtil::Time& retryInterval) :
+ mMgr(mgr),
+ mStopped(false),
+ mRetryInterval(retryInterval)
+
+ {
+ }
+
+ void run()
+ {
+ bool initialized = false;
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(mMonitor);
+ while(!mStopped && !initialized)
+ {
+ mMonitor.timedWait(mRetryInterval);
+ initialized = mMgr->init();
+ }
+ }
+
+ void stop()
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(mMonitor);
+ mStopped = true;
+ mMonitor.notify();
+ }
+
+ private:
+ IceUtil::Monitor<IceUtil::Mutex> mMonitor;
+ typename IceUtil::Handle<ListenerManagerT> mMgr;
+ bool mStopped;
+ const IceUtil::Time mRetryInterval;
+ };
+
+public:
+ ListenerManagerT(const IceStorm::TopicManagerPrx& topicManager, const std::string& topicName,
+ bool enableBackgroundInit,
+ const IceUtil::Time& retryInterval) :
+ mTopicManager(topicManager),
+ mTopicName(topicName),
+ mInitialized(false)
+ {
+ try
+ {
+ init();
+ }
+ catch(const Ice::Exception&)
+ {
+ }
+
+ if(!mInitialized && enableBackgroundInit)
+ {
+ mInitThread = new InitializationThread(this, retryInterval);
+ mInitThread->start();
+ }
+ }
+
+ virtual ~ListenerManagerT()
+ {
+ if(mTopic)
+ {
+ try
+ {
+ mTopic->destroy();
+ }
+ catch(...)
+ {
+ //
+ // Destructors are no-throw!
+ //
+ }
+ }
+ }
+
+ //
+ // NOTE: The current implementation is a little fast and loose here. Inconsistent conditions
+ // and whatnot are not flagged.
+ //
+ bool addListener(const T& listener)
+ {
+ bool tryInit = false;
+ bool added = false;
+ {
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
+ if(std::find(mListeners.begin(), mListeners.end(), listener) == mListeners.end())
+ {
+ mListeners.push_back(listener);
+ added = true;
+ }
+ tryInit = !mInitialized && !mInitThread;
+ }
+
+ if (!tryInit)
+ {
+ if (added)
+ {
+ IceStorm::QoS qos;
+ qos["reliability"] = "ordered";
+
+ try
+ {
+ mTopic->subscribeAndGetPublisher(qos, listener);
+ }
+ catch (const IceStorm::AlreadySubscribed&)
+ {
+ //
+ // This indicates some kind of inconsistent state or could
+ // happen if this is a replica.
+ //
+ }
+ }
+ }
+ else
+ {
+ init();
+ }
+
+ return added;
+ }
+
+ bool removeListener(const T& listener)
+ {
+ T& proxyToUnsubscribe;
+ {
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
+ typename std::vector<T>::iterator i = std::find(mListeners.begin(), mListeners.end(), listener);
+ if(i != mListeners.end())
+ {
+ mListeners.erase(i);
+ if(mInitialized)
+ {
+ proxyToUnsubscribe = listener;
+ }
+ }
+ }
+ if (proxyToUnsubscribe)
+ {
+ mTopic->unsubscribe(proxyToUnsubscribe);
+ return true;
+ }
+ return false;
+ }
+
+ std::vector<T> getListeners()
+ {
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
+ return mListeners;
+ }
+
+ bool isSuspended()
+ {
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
+ return !mInitialized;
+ }
+
+ void stop()
+ {
+ if(mInitThread)
+ {
+ mInitThread->stop();
+ }
+ }
+
+protected:
+ boost::shared_mutex mLock;
+ std::string mTopicName;
+ IceStorm::TopicPrx mTopic;
+ IceStorm::TopicManagerPrx mTopicManager;
+ T mPublisher;
+ ListenerSeq mListeners;
+ IceUtil::Handle<InitializationThread> mInitThread;
+
+ bool mInitialized;
+
+ bool init()
+ {
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
+ if (mInitialized)
+ {
+ return mInitialized;
+ }
+
+ //
+ // This *might* be the first time we attempt to access IceStorm. If so, then the connection
+ // might fail because it may not be available at the moment. If so, we "eat" the resulting
+ // SocketException and reply that we are not initialized. All other exceptions propogate
+ // out as they typically indicated a terminal condition.
+ //
+ try
+ {
+ mTopic = mTopicManager->retrieve(mTopicName);
+ }
+ catch (const IceStorm::NoSuchTopic&)
+ {
+ //
+ // We ignore this.. we'll try to create it below if it doesn't exist.
+ //
+ }
+ catch (const Ice::SocketException&)
+ {
+ return false;
+ }
+
+ if(!mTopic)
+ {
+ try
+ {
+ mTopic = mTopicManager->create(mTopicName);
+ }
+ catch(const IceStorm::TopicExists&)
+ {
+ //
+ // In case there is a race condition when creating the topic.
+ //
+ mTopic = mTopicManager->retrieve(mTopicName);
+ }
+ }
+
+ if(!mTopic)
+ {
+ return mInitialized;
+ }
+ mPublisher = T::uncheckedCast(mTopic->getPublisher());
+
+ if(mListeners.size() > 0)
+ {
+ for(typename std::vector<T>::iterator i = mListeners.begin(); i != mListeners.end(); ++i)
+ {
+ //
+ // This could be made configurable, but for the ordered QoS is appropriate for most
+ // listener models.
+ //
+ IceStorm::QoS qos;
+ qos["reliability"] = "ordered";
+
+ try
+ {
+ mTopic->subscribeAndGetPublisher(qos, *i);
+ }
+ catch(const IceStorm::AlreadySubscribed&)
+ {
+ //
+ // This indicates some kind of inconsistent state.
+ //
+ }
+ }
+ }
+ mInitialized = true;
+ return mInitialized;
+ }
+};
+} /* End of namespace AsteriskSCF */
diff --git a/StateReplicator/include/AsteriskSCF/StateReplicator.h b/include/AsteriskSCF/Replication/StateReplicator.h
similarity index 99%
rename from StateReplicator/include/AsteriskSCF/StateReplicator.h
rename to include/AsteriskSCF/Replication/StateReplicator.h
index 0186142..e75e4ea 100644
--- a/StateReplicator/include/AsteriskSCF/StateReplicator.h
+++ b/include/AsteriskSCF/Replication/StateReplicator.h
@@ -22,7 +22,7 @@
namespace AsteriskSCF
{
-namespace StateReplication
+namespace Replication
{
/**
diff --git a/TestFixture/include/AsteriskSCF/IceBoxBoostTest.h b/include/AsteriskSCF/Testing/IceBoxBoostTest.h
similarity index 100%
rename from TestFixture/include/AsteriskSCF/IceBoxBoostTest.h
rename to include/AsteriskSCF/Testing/IceBoxBoostTest.h
diff --git a/ThreadPool/include/AsteriskSCF/ThreadPool.h b/include/AsteriskSCF/ThreadPool/ThreadPool.h
similarity index 100%
rename from ThreadPool/include/AsteriskSCF/ThreadPool.h
rename to include/AsteriskSCF/ThreadPool/ThreadPool.h
diff --git a/ThreadPool/include/AsteriskSCF/WorkerThread.h b/include/AsteriskSCF/ThreadPool/WorkerThread.h
similarity index 100%
rename from ThreadPool/include/AsteriskSCF/WorkerThread.h
rename to include/AsteriskSCF/ThreadPool/WorkerThread.h
diff --git a/WorkQueue/test/test.cpp b/include/AsteriskSCF/Utilities.h
similarity index 50%
copy from WorkQueue/test/test.cpp
copy to include/AsteriskSCF/Utilities.h
index b19fc86..5534b29 100644
--- a/WorkQueue/test/test.cpp
+++ b/include/AsteriskSCF/Utilities.h
@@ -14,5 +14,18 @@
* at the top of the source tree.
*/
-#define BOOST_TEST_MODULE WorkQueue
-#include <boost/test/unit_test.hpp>
+#pragma once
+#include <AsteriskSCF/Helpers/ProxyHelper.h>
+#include <AsteriskSCF/Helpers/PropertyHelper.h>
+#include <AsteriskSCF/Discovery/LocatorRegistrationWrapper.h>
+#include <AsteriskSCF/Discovery/SmartProxy.h>
+#include <AsteriskSCF/Listener/ListenerManager.h>
+#include <AsteriskSCF/Async/AmiCollector.h>
+#include <AsteriskSCF/Async/ResponseCollector.h>
+#include <AsteriskSCF/Replication/StateReplicator.h>
+
+//
+// The testing header file is deliberately left out as it is not intended for use in implementing components.
+//
+
+
diff --git a/WorkQueue/include/AsteriskSCF/DefaultQueueListener.h b/include/AsteriskSCF/WorkQueue/DefaultQueueListener.h
similarity index 100%
rename from WorkQueue/include/AsteriskSCF/DefaultQueueListener.h
rename to include/AsteriskSCF/WorkQueue/DefaultQueueListener.h
diff --git a/WorkQueue/include/AsteriskSCF/SuspendableWorkQueue.h b/include/AsteriskSCF/WorkQueue/SuspendableWorkQueue.h
similarity index 100%
rename from WorkQueue/include/AsteriskSCF/SuspendableWorkQueue.h
rename to include/AsteriskSCF/WorkQueue/SuspendableWorkQueue.h
diff --git a/WorkQueue/include/AsteriskSCF/WorkQueue.h b/include/AsteriskSCF/WorkQueue/WorkQueue.h
similarity index 100%
rename from WorkQueue/include/AsteriskSCF/WorkQueue.h
rename to include/AsteriskSCF/WorkQueue/WorkQueue.h
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..6bd28d1
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,59 @@
+#
+# Asterisk Scalable Communications Framework
+#
+# Copyright (C) 2010 -- Digium, Inc.
+#
+# All rights reserved.
+#
+
+# Ice Utilities for C++
+
+asterisk_scf_component_init(ice-util-cpp)
+
+include_directories(../include)
+asterisk_scf_slice_include_directories(${API_SLICE_DIR})
+
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Discovery/SmartProxy.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Discovery/LocatorRegistrationWrapper.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Async/AmiCollector.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Async/ResponseCollector.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Helpers/PropertyHelper.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Helpers/ProxyHelper.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Helpers/Retry.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Listener/ListenerManager.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Replication/StateReplicator.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/WorkQueue/WorkQueue.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/WorkQueue/SuspendableWorkQueue.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/WorkQueue/DefaultQueueListener.h)
+asterisk_scf_component_add_file(ice-util-cpp WorkQueue/WorkQueue.cpp)
+asterisk_scf_component_add_file(ice-util-cpp WorkQueue/SuspendableWorkQueue.cpp)
+asterisk_scf_component_add_file(ice-util-cpp WorkQueue/DefaultQueueListener.cpp)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/ThreadPool/ThreadPool.h)
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/ThreadPool/WorkerThread.h)
+asterisk_scf_component_add_file(ice-util-cpp ThreadPool/ThreadPool.cpp)
+asterisk_scf_component_add_file(ice-util-cpp ThreadPool/WorkerThread.cpp)
+
+#
+# Note, strictly speaking this isn't for component development, but as it is part of this
+# library it sort of belongs here.
+#
+asterisk_scf_component_add_file(ice-util-cpp ../include/AsteriskSCF/Testing/IceBoxBoostTest.h)
+
+asterisk_scf_component_add_file(ice-util-cpp IceUtilCpp.cpp)
+asterisk_scf_component_add_boost_libraries(ice-util-cpp core thread date_time)
+
+if(NOT logger_dir)
+ message(FATAL_ERROR "The logger directory could not be found ${logger_dir}")
+endif()
+include_directories(${logger_dir}/include)
+include_directories(${API_INCLUDE_DIR})
+
+asterisk_scf_component_build_library(ice-util-cpp)
+
+include_directories(${API_INCLUDE_DIR})
+target_link_libraries(ice-util-cpp logging-client)
+target_link_libraries(ice-util-cpp asterisk-scf-api)
+
+# don't install the component. it's just there to make Visual Studio happy
+# _do_ install the header files
+asterisk_scf_headers_install(include/)
diff --git a/SmartProxy/src/SmartProxy.cpp b/src/IceUtilCpp.cpp
similarity index 77%
copy from SmartProxy/src/SmartProxy.cpp
copy to src/IceUtilCpp.cpp
index 2ebb5d7..d05edd5 100644
--- a/SmartProxy/src/SmartProxy.cpp
+++ b/src/IceUtilCpp.cpp
@@ -13,17 +13,9 @@
* the GNU General Public License Version 2. See the LICENSE.txt file
* at the top of the source tree.
*/
+#include <Ice/Ice.h>
+#include <AsteriskSCF/Utilities.h>
-#include <AsteriskSCF/SmartProxy.h>
-
-namespace AsteriskSCF
-{
-namespace ProxyWrapper
-{
-/*
- * This .cpp is a temporary solution to get a CMakeProject that consists only of header files.
- */
-
-};
-
-};
+//
+// This .cpp is a temporary solution to get a CMakeProject that consists only of header files.
+//
diff --git a/ThreadPool/src/CMakeLists.txt b/src/ThreadPool/CMakeLists.txt
similarity index 100%
rename from ThreadPool/src/CMakeLists.txt
rename to src/ThreadPool/CMakeLists.txt
diff --git a/ThreadPool/src/ThreadPool.cpp b/src/ThreadPool/ThreadPool.cpp
similarity index 98%
rename from ThreadPool/src/ThreadPool.cpp
rename to src/ThreadPool/ThreadPool.cpp
index 5ed3c76..fb7e601 100644
--- a/ThreadPool/src/ThreadPool.cpp
+++ b/src/ThreadPool/ThreadPool.cpp
@@ -16,10 +16,10 @@
#include <boost/thread.hpp>
-#include <AsteriskSCF/ThreadPool.h>
-#include <AsteriskSCF/WorkerThread.h>
-#include <AsteriskSCF/WorkQueue.h>
-#include <AsteriskSCF/DefaultQueueListener.h>
+#include <AsteriskSCF/ThreadPool/ThreadPool.h>
+#include <AsteriskSCF/ThreadPool/WorkerThread.h>
+#include <AsteriskSCF/WorkQueue/WorkQueue.h>
+#include <AsteriskSCF/WorkQueue/DefaultQueueListener.h>
namespace AsteriskSCF
{
diff --git a/ThreadPool/src/WorkerThread.cpp b/src/ThreadPool/WorkerThread.cpp
similarity index 98%
rename from ThreadPool/src/WorkerThread.cpp
rename to src/ThreadPool/WorkerThread.cpp
index 59cef80..6f8b59f 100644
--- a/ThreadPool/src/WorkerThread.cpp
+++ b/src/ThreadPool/WorkerThread.cpp
@@ -17,7 +17,7 @@
#include <boost/thread.hpp>
#include <AsteriskSCF/System/WorkQueue/WorkQueueIf.h>
-#include <AsteriskSCF/WorkerThread.h>
+#include <AsteriskSCF/ThreadPool/WorkerThread.h>
namespace AsteriskSCF
{
diff --git a/WorkQueue/src/CMakeLists.txt b/src/WorkQueue/CMakeLists.txt
similarity index 100%
rename from WorkQueue/src/CMakeLists.txt
rename to src/WorkQueue/CMakeLists.txt
diff --git a/WorkQueue/src/DefaultQueueListener.cpp b/src/WorkQueue/DefaultQueueListener.cpp
similarity index 97%
rename from WorkQueue/src/DefaultQueueListener.cpp
rename to src/WorkQueue/DefaultQueueListener.cpp
index 9a55341..cccf50b 100644
--- a/WorkQueue/src/DefaultQueueListener.cpp
+++ b/src/WorkQueue/DefaultQueueListener.cpp
@@ -15,7 +15,7 @@
*/
#include <boost/thread.hpp>
-#include <AsteriskSCF/DefaultQueueListener.h>
+#include <AsteriskSCF/WorkQueue/DefaultQueueListener.h>
namespace AsteriskSCF
{
diff --git a/WorkQueue/src/SuspendableWorkQueue.cpp b/src/WorkQueue/SuspendableWorkQueue.cpp
similarity index 99%
rename from WorkQueue/src/SuspendableWorkQueue.cpp
rename to src/WorkQueue/SuspendableWorkQueue.cpp
index 9ebd078..771adc0 100644
--- a/WorkQueue/src/SuspendableWorkQueue.cpp
+++ b/src/WorkQueue/SuspendableWorkQueue.cpp
@@ -18,7 +18,7 @@
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
-#include <AsteriskSCF/SuspendableWorkQueue.h>
+#include <AsteriskSCF/WorkQueue/SuspendableWorkQueue.h>
namespace AsteriskSCF
{
diff --git a/WorkQueue/src/WorkQueue.cpp b/src/WorkQueue/WorkQueue.cpp
similarity index 98%
rename from WorkQueue/src/WorkQueue.cpp
rename to src/WorkQueue/WorkQueue.cpp
index abec3b0..d31cf25 100644
--- a/WorkQueue/src/WorkQueue.cpp
+++ b/src/WorkQueue/WorkQueue.cpp
@@ -18,7 +18,7 @@
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
-#include <AsteriskSCF/WorkQueue.h>
+#include <AsteriskSCF/WorkQueue/WorkQueue.h>
namespace AsteriskSCF
{
diff --git a/AmiCollector/test/CMakeLists.txt b/test/Async/CMakeLists.txt
similarity index 100%
rename from AmiCollector/test/CMakeLists.txt
rename to test/Async/CMakeLists.txt
diff --git a/AmiCollector/test/IceIntegration-test.cpp b/test/Async/IceIntegration-test.cpp
similarity index 97%
rename from AmiCollector/test/IceIntegration-test.cpp
rename to test/Async/IceIntegration-test.cpp
index 3a2626a..019f4ea 100644
--- a/AmiCollector/test/IceIntegration-test.cpp
+++ b/test/Async/IceIntegration-test.cpp
@@ -18,11 +18,11 @@
#include <Ice/Proxy.h>
#include <boost/test/unit_test.hpp>
-#include <AsteriskSCF/AmiCollector.h>
+#include <AsteriskSCF/Async/AmiCollector.h>
#include "TestAmiCollector.h"
-using namespace AsteriskSCF::IceUtil;
+using namespace AsteriskSCF;
namespace
{
diff --git a/AmiCollector/test/ResponseCollector-test.cpp b/test/Async/ResponseCollector-test.cpp
similarity index 95%
rename from AmiCollector/test/ResponseCollector-test.cpp
rename to test/Async/ResponseCollector-test.cpp
index af94552..09bff4c 100644
--- a/AmiCollector/test/ResponseCollector-test.cpp
+++ b/test/Async/ResponseCollector-test.cpp
@@ -16,7 +16,7 @@
#include <boost/test/unit_test.hpp>
-#include <AsteriskSCF/ResponseCollector.h>
+#include <AsteriskSCF/Async/ResponseCollector.h>
using namespace AsteriskSCF;
@@ -28,7 +28,7 @@ public:
const char* what() const throw() { return "TestException"; }
};
-class TestCollector : public ResponseCollector<bool>
+class TestCollector : public AsteriskSCF::Async::ResponseCollector<bool>
{
public:
/** Num results received */
diff --git a/AmiCollector/test/TestAmiCollector.h b/test/Async/TestAmiCollector.h
similarity index 92%
rename from AmiCollector/test/TestAmiCollector.h
rename to test/Async/TestAmiCollector.h
index 41fae09..f30b66a 100644
--- a/AmiCollector/test/TestAmiCollector.h
+++ b/test/Async/TestAmiCollector.h
@@ -17,17 +17,15 @@
#include <boost/thread/condition_variable.hpp>
#include <IceUtil/Handle.h>
-#include <AsteriskSCF/AmiCollector.h>
+#include <AsteriskSCF/Async/AmiCollector.h>
namespace AsteriskSCF
{
-namespace IceUtil
-{
/**
* Simple AMI collector for testing
*/
-class TestAmiCollector : public AsteriskSCF::IceUtil::AmiCollector<
+class TestAmiCollector : public AsteriskSCF::Async::AmiCollector<
bool,
Ice::ObjectPrx,
&Ice::ObjectPrx::element_type::end_ice_isA>
@@ -81,5 +79,4 @@ private:
typedef ::IceUtil::Handle<TestAmiCollector> TestAmiCollectorPtr;
-} // IceUtil
} // AsteriskSCF
diff --git a/AmiCollector/test/test.cpp b/test/Async/test.cpp
similarity index 100%
rename from AmiCollector/test/test.cpp
rename to test/Async/test.cpp
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..40b9f87
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,22 @@
+asterisk_scf_slice_include_directories(${API_SLICE_DIR})
+asterisk_scf_component_init(ice-util-cpp-test CXX)
+include_directories("../include")
+asterisk_scf_component_add_slice(ice-util-cpp-test ./ProxyHelper/SimpleIf.ice)
+asterisk_scf_component_add_file(ice-util-cpp-test ./LocatorRegistration/LocatorRegistrationTest.cpp)
+asterisk_scf_component_add_file(ice-util-cpp-test ./LocatorRegistration/LocatorRegistrationTest.h)
+asterisk_scf_component_add_file(ice-util-cpp-test ./PropertyHelper/PropertyHelperTest.cpp)
+asterisk_scf_component_add_file(ice-util-cpp-test ./PropertyHelper/PropertyHelperTest.h)
+asterisk_scf_component_add_file(ice-util-cpp-test ./ProxyHelper/ProxyHelperTests.cpp)
+asterisk_scf_component_add_file(ice-util-cpp-test ./ProxyHelper/ProxyHelperTests.h)
+asterisk_scf_component_add_file(ice-util-cpp-test UtilityTests.cpp)
+
+asterisk_scf_component_add_ice_libraries(ice-util-cpp-test IceBox)
+asterisk_scf_component_add_boost_libraries(ice-util-cpp-test unit_test_framework date_time thread)
+
+include_directories(${API_INCLUDE_DIR})
+asterisk_scf_component_build_icebox(ice-util-cpp-test)
+target_link_libraries(ice-util-cpp-test asterisk-scf-api)
+
+add_subdirectory(Async)
+add_subdirectory(Replication)
+
diff --git a/WorkQueue/test/test2.cpp b/test/ListenerManager/ListenerManagerTests.cpp
similarity index 74%
copy from WorkQueue/test/test2.cpp
copy to test/ListenerManager/ListenerManagerTests.cpp
index 81310b6..a413887 100644
--- a/WorkQueue/test/test2.cpp
+++ b/test/ListenerManager/ListenerManagerTests.cpp
@@ -1,7 +1,7 @@
/*
* Asterisk SCF -- An open-source communications framework.
*
- * Copyright (C) 2011, Digium, Inc.
+ * Copyright (C) 2010-2011, Digium, Inc.
*
* See http://www.asterisk.org for more information about
* the Asterisk SCF project. Please do not directly contact
@@ -14,5 +14,14 @@
* at the top of the source tree.
*/
-#define BOOST_TEST_MODULE SuspendableWorkQueue
+#include <boost/bind.hpp>
#include <boost/test/unit_test.hpp>
+#include <boost/test/debug.hpp>
+
+#include <Ice/Ice.h>
+#include <IceBox/IceBox.h>
+
+#include <AsteriskSCF/IceUtility.h>
+
+
+
diff --git a/test/LocatorRegistration/LocatorRegistrationTest.cpp b/test/LocatorRegistration/LocatorRegistrationTest.cpp
new file mode 100644
index 0000000..6ce9af5
--- /dev/null
+++ b/test/LocatorRegistration/LocatorRegistrationTest.cpp
@@ -0,0 +1,700 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010-2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+#include <Ice/Ice.h>
+#include <IceBox/IceBox.h>
+#include <IceUtil/Thread.h>
+#include <IceUtil/UUID.h>
+
+#include <AsteriskSCF/Discovery/LocatorRegistrationWrapper.h>
+#include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
+#include <AsteriskSCF/Core/Discovery/ServiceLocatorEventsIf.h>
+
+#include <boost/test/unit_test.hpp>
+#include <boost/bind.hpp>
+#include <boost/test/debug.hpp>
+
+#include <vector>
+#include <string>
+#include <map>
+#include <AsteriskSCF/Helpers/PropertyHelper.h>
+#include <AsteriskSCF/Helpers/ProxyHelper.h>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include "LocatorRegistrationTest.h"
+
+using namespace std;
+using namespace boost::unit_test;
+using namespace AsteriskSCF::Discovery;
+
+namespace AsteriskSCF
+{
+namespace LocatorRegistrationTests
+{
+
+//
+// NOTE:
+// This test contains a mock locator. It's a little "overkill" for this particular test in that
+// it implements features that aren't used at the moment. As this is a test for a helper class
+// in the utility library it did not make sense to introduce a physical or runtime dependency
+// on a service that might also use the thing being tested.
+//
+
+//
+// The data associated with a registration is shared amongst multiple objects. To avoid
+// circular references, it is placed into a reference counted object of its own. You end
+// up with some additional dereferencing, but 0 circular references.
+//
+class RegistrationData : public IceUtil::Shared
+{
+ typedef map<std::string, AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr> ParamMap;
+public:
+ RegistrationData() :
+ mState(AsteriskSCF::Core::Discovery::V1::Active),
+ mDestroyed(false)
+ {
+ }
+
+ AsteriskSCF::Core::Discovery::V1::ServiceStatus state()
+ {
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
+ return mState;
+ }
+
+ void suspend()
+ {
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
+ mState = AsteriskSCF::Core::Discovery::V1::Suspended;
+ }
+
+ void unsuspend()
+ {
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
+ mState = AsteriskSCF::Core::Discovery::V1::Active;
+ }
+
+ void add(const std::string& id, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr& p)
+ {
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
+ mParameters[id] = p;
+ }
+
+ bool destroy()
+ {
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
+ if (mDestroyed)
+ {
+ return false;
+ }
+ mDestroyed = true;
+ return mDestroyed;
+ }
+
+ bool isDestroyed()
+ {
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
+ return mDestroyed;
+ }
+
+ bool match(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr& p)
+ {
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
+ for (ParamMap::const_iterator i = mParameters.begin(); i != mParameters.end(); ++i)
+ {
+ if (i->second->category == p->category)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+private:
+ boost::shared_mutex mLock;
+ AsteriskSCF::Core::Discovery::V1::ServiceStatus mState;
+ ParamMap mParameters;
+ bool mDestroyed;
+};
+typedef IceUtil::Handle<RegistrationData> RegistrationDataPtr;
+
+class RegistrationToken : public AsteriskSCF::Core::Discovery::V1::ServiceManagement
+{
+public:
+
+ RegistrationToken(const RegistrationDataPtr& d) :
+ mData(d)
+ {
+ }
+
+ void addLocatorParams(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr& params,
+ const std::string& compareGUID,
+ const Ice::Current&)
+ {
+ statePreCheck();
+ mData->add(compareGUID, params);
+ }
+
+ AsteriskSCF::Core::Discovery::V1::ServiceStatus getStatus(const Ice::Current&) const
+ {
+ statePreCheck();
+ return mData->state();
+ }
+
+ void suspend(const Ice::Current&)
+ {
+ statePreCheck();
+ mData->suspend();
+ }
+
+ void unsuspend(const Ice::Current&)
+ {
+ statePreCheck();
+ mData->unsuspend();
+ }
+
+ void unregister(const Ice::Current&)
+ {
+ if (!mData->destroy())
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ }
+
+ void statePreCheck() const
+ {
+ if (mData->isDestroyed())
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ }
+
+private:
+ IceUtil::Handle<RegistrationData> mData;
+};
+
+class RegistrationHandler : public IceUtil::Shared
+{
+public:
+ RegistrationHandler(const std::string& id, const Ice::ObjectPrx& obj, const Ice::ObjectAdapterPtr& adapter) :
+ mId(id),
+ mObj(obj),
+ mAdapter(adapter),
+ mData(new RegistrationData)
+ {
+ }
+
+ AsteriskSCF::Core::Discovery::V1::ServiceStatus state() const
+ {
+ return mData->state();
+ }
+
+ void suspend()
+ {
+ mData->suspend();
+ }
... 14300 lines suppressed ...
--
asterisk-scf/integration/ice-util-cpp.git
More information about the asterisk-scf-commits
mailing list