[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