[asterisk-scf-commits] asterisk-scf/integration/file_session_gateway.git branch "initial_development" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Fri Dec 2 14:05:06 CST 2011


branch "initial_development" has been updated
       via  a54a6d7f641f1dbb824e6d7643a58c5bd279eb5a (commit)
       via  942d5f831153caa82e016491751a94d0ddd3d0db (commit)
       via  d776214a336cc0fa3e1666fe004f42b90b4b566d (commit)
       via  76ae057575c077c85916e9a61b720bcb2f1c4d63 (commit)
       via  3af7e78132b80618f1b2bd55cb64e881488f6f8e (commit)
       via  747eac780f3d17274f9eabe07709b36b15742468 (commit)
       via  5bf86c70bfa65017fa77601064a1611b8c4e14ad (commit)
       via  d7821023155078488fc3f0815ac7883f9c778138 (commit)
       via  4da7213abc36a6810c67556a37d880d394655d8f (commit)
       via  ed1903c33e3909379908a6dba957c3c761788590 (commit)
      from  14fe2bc3b206ca70ae95f2e2537df1bbd32068ae (commit)

Summary of changes:
 config/FileSessionGateway.config                   |   43 +++-
 config/FileSessionGatewayConfigurator.py           |   26 ++-
 config/file_session_gateway.icebox                 |   60 +++-
 config/test_file_session_gateway.icebox            |   86 +++++
 .../FileSessionGateway/FileSessionGatewayIf.ice    |    1 +
 src/CMakeLists.txt                                 |    2 +
 src/Component.cpp                                  |   46 +++-
 src/Configuration.cpp                              |   68 +++--
 src/Configuration.h                                |    4 +-
 src/Endpoint.cpp                                   |   12 +-
 src/Endpoint.h                                     |    2 +
 src/EndpointLocator.cpp                            |  307 ++++++++++++++++--
 src/EndpointLocator.h                              |    4 +-
 src/RemoteServices.cpp                             |  130 +++++++
 src/RemoteServices.h                               |   56 +++
 src/Session.cpp                                    |  355 +++++++++++++++++---
 src/Session.h                                      |    6 +
 test/CMakeLists.txt                                |   13 +
 test/ComponentTest.cpp                             |  351 +++++++++++++++++++
 test/TestEndpointLocator.cpp                       |    4 +-
 test/TestSessionObject.cpp                         |    8 +-
 21 files changed, 1465 insertions(+), 119 deletions(-)
 create mode 100644 config/test_file_session_gateway.icebox
 create mode 100644 src/RemoteServices.cpp
 create mode 100644 src/RemoteServices.h
 create mode 100644 test/ComponentTest.cpp


- Log -----------------------------------------------------------------
commit a54a6d7f641f1dbb824e6d7643a58c5bd279eb5a
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Dec 2 16:22:20 2011 -0330

    Fix off by one error in args processing in component test.

diff --git a/config/test_file_session_gateway.icebox b/config/test_file_session_gateway.icebox
index ddf95e2..fbdf501 100644
--- a/config/test_file_session_gateway.icebox
+++ b/config/test_file_session_gateway.icebox
@@ -46,19 +46,19 @@ ServiceDiscovery.Management.ServiceAdapter.ThreadPool.Size=4
 
 BridgeService.BridgeManagerObjectId=TestBridge
 BridgeService.Standalone=true
-BridgeService.ServiceAdapter.Endpoints=default -p 57000
+BridgeService.ServiceAdapter.Endpoints=default -p 5701
 BridgeService.ServiceAdapter.ThreadPool.Size=4
-BridgeService.BackplaneAdapter.Endpoints=default -p 57001
+BridgeService.BackplaneAdapter.Endpoints=default -p 5702
 BridgeService.BackplaneAdapter.ThreadPool.Size=4
 
-RoutingService.ServiceAdapter.Endpoints=default -p 10050
+RoutingService.ServiceAdapter.Endpoints=default -p 5750
 RoutingService.ServiceAdapter.ThreadPool.Size=4
 RoutingService.Standalone=true
-RoutingService.BackplaneAdapter.Endpoints=default -p 10051
+RoutingService.BackplaneAdapter.Endpoints=default -p 5751
 
-FileSessionGateway.ServiceAdapter.Endpoints=default -p 58001
+FileSessionGateway.ServiceAdapter.Endpoints=default -p 5851
 FileSessionGateway.ServiceAdapter.ThreadPool.Size=4
-FileSessionGateway.BackplaneAdapter.Endpoints=default -p 58002
+FileSessionGateway.BackplaneAdapter.Endpoints=default -p 5852
 FileSessionGateway.BackplaneAdapter.ThreadPool.Size=4
 FileSessionGateway.Standalone=true
 
@@ -66,7 +66,7 @@ FileSessionGateway.Standalone=true
 # Load the ancillary componnents
 #
 IceBox.Service.Logger=logging-service:createLoggingService
-IceBox.Service.Replicator=FileSessionGatewayReplicator:create
+IceBox.Service.Replicator=FileSessionReplicator:create
 IceBox.Service.RoutingService=BasicRoutingService:create
 IceBox.Service.BridgeService=bridgeservice:create
 IceBox.Service.ServiceDiscovery=service_locator:create
@@ -77,7 +77,7 @@ IceBox.Service.ServiceDiscovery=service_locator:create
 IceBox.Service.FileSessionGateway=FileSessionGateway:create
 IceBox.Service.GatewayTester=FileSessionGatewayTest:create
 
-IceBox.LoadOrder=ServiceDiscovery Logger BridgeService RoutingService Replicator FileSessionGateway GatewayTester
+IceBox.LoadOrder=ServiceDiscovery Logger RoutingService Replicator FileSessionGateway GatewayTester
 
 IceBox.ServiceManager.Endpoints=default -p 56000
 IceBox.ServiceManager.ThreadPool.Size=4
diff --git a/test/ComponentTest.cpp b/test/ComponentTest.cpp
index fee0916..d4a48ce 100644
--- a/test/ComponentTest.cpp
+++ b/test/ComponentTest.cpp
@@ -60,8 +60,7 @@ class FileSessionGatewaySuite : public boost::enable_shared_from_this<FileSessio
 public:
     FileSessionGatewaySuite(const Ice::CommunicatorPtr& communicator, const Ice::StringSeq& args):
         mCommunicator(communicator),
-        mArgs(args),
-        mArgv(0)
+        mArgs(args)
     {
         mArgs.insert(mArgs.begin(), "FileSessionGatewayTest");
         for (Ice::StringSeq::const_iterator argIter = mArgs.begin(); argIter != mArgs.end(); ++argIter)
@@ -77,7 +76,7 @@ public:
 
     size_t argc()
     {
-        return mArgv.size();
+        return mArgv.size() -1;
     }
 
     char** argv()
@@ -299,11 +298,16 @@ public:
                 manager->shutdown();
             }
         }
+        catch (const std::exception& ex)
+        {
+            cerr << "Completely unexpected badness in the form of " << ex.what() << endl;
+        }
         catch (...)
         {
             //
             // not much to happen here... we tried.
             //
+            cerr << "unknown badness!" << endl;
         }
     }
     

commit 942d5f831153caa82e016491751a94d0ddd3d0db
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Dec 2 14:49:45 2011 -0330

    Fix missing return value.

diff --git a/config/test_file_session_gateway.icebox b/config/test_file_session_gateway.icebox
index e4e746f..ddf95e2 100644
--- a/config/test_file_session_gateway.icebox
+++ b/config/test_file_session_gateway.icebox
@@ -4,7 +4,7 @@
 
 # All services loaded by this configuration file should also load these
 # properties.
-Ice.InheritProperties=1
+IceBox.InheritProperties=1
 
 #
 # Some APIs are generated as AMD and some internal calls may use AMI, both
diff --git a/test/ComponentTest.cpp b/test/ComponentTest.cpp
index 0355d37..fee0916 100644
--- a/test/ComponentTest.cpp
+++ b/test/ComponentTest.cpp
@@ -268,6 +268,7 @@ bool init_unit_test()
 {
     framework::master_test_suite().add(
         BOOST_TEST_CASE(boost::bind(&FileSessionGatewaySuite::endpointLocatorTest, GatewayTest)));
+    return true;
 }
 
 

commit d776214a336cc0fa3e1666fe004f42b90b4b566d
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Dec 2 14:39:15 2011 -0330

    - Add a category and a registration for the file session gateway's endpoint
      locator.
    
    - Fill out a component test that wasn't working because of omission above.

diff --git a/config/test_file_session_gateway.icebox b/config/test_file_session_gateway.icebox
index 8d6720a..e4e746f 100644
--- a/config/test_file_session_gateway.icebox
+++ b/config/test_file_session_gateway.icebox
@@ -53,13 +53,14 @@ BridgeService.BackplaneAdapter.ThreadPool.Size=4
 
 RoutingService.ServiceAdapter.Endpoints=default -p 10050
 RoutingService.ServiceAdapter.ThreadPool.Size=4
-RoutingService.Stanadlone=true
+RoutingService.Standalone=true
 RoutingService.BackplaneAdapter.Endpoints=default -p 10051
 
 FileSessionGateway.ServiceAdapter.Endpoints=default -p 58001
 FileSessionGateway.ServiceAdapter.ThreadPool.Size=4
 FileSessionGateway.BackplaneAdapter.Endpoints=default -p 58002
 FileSessionGateway.BackplaneAdapter.ThreadPool.Size=4
+FileSessionGateway.Standalone=true
 
 #
 # Load the ancillary componnents
@@ -81,3 +82,5 @@ IceBox.LoadOrder=ServiceDiscovery Logger BridgeService RoutingService Replicator
 IceBox.ServiceManager.Endpoints=default -p 56000
 IceBox.ServiceManager.ThreadPool.Size=4
 IceBoxMgr.Proxy=IceBox/ServiceManager:default -p 56000
+
+Test.MediaServiceName=testFileMedia
diff --git a/slice/AsteriskSCF/FileSessionGateway/FileSessionGatewayIf.ice b/slice/AsteriskSCF/FileSessionGateway/FileSessionGatewayIf.ice
index fa9434e..94f0531 100755
--- a/slice/AsteriskSCF/FileSessionGateway/FileSessionGatewayIf.ice
+++ b/slice/AsteriskSCF/FileSessionGateway/FileSessionGatewayIf.ice
@@ -24,6 +24,7 @@ module V1
 {
 
 const string ComponentServiceDiscoveryCategory = "FileSessionGateway";
+const string EndpointLocatorDiscoveryCategory = "FileSessionGateway.EndpointLocator";
     
 }; /* end of module V1 */
 }; /* end of module FileSessionGatway */
diff --git a/src/EndpointLocator.cpp b/src/EndpointLocator.cpp
index d7d60dc..135d197 100644
--- a/src/EndpointLocator.cpp
+++ b/src/EndpointLocator.cpp
@@ -23,6 +23,7 @@
 #include <AsteriskSCF/Core/Routing/RoutingIf.h>
 #include <AsteriskSCF/Core/Endpoint/EndpointIf.h>
 #include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
+#include <AsteriskSCF/FileSessionGateway/FileSessionGatewayIf.h>
 
 #include <IceUtil/UUID.h>
 #include <IceUtil/Thread.h>
@@ -740,13 +741,18 @@ public:
         return mProxy;
     }
 
-    void registerFeature(const FileSessionGatewayComponentPtr&)
+    void registerFeature(const FileSessionGatewayComponentPtr& gatewayComponent)
     {
-        //
-        // Hrmm.. I don't think we register to the locator, but we do register
-        // the endpoint locator with the router's thing. This might not be the
-        // place to do it.
-        //
+        assert(gatewayComponent);
+        if (gatewayComponent)
+        {
+            gatewayComponent->addFeatureProxyToServices(mProxy,
+                AsteriskSCF::FileSessionGateway::V1::EndpointLocatorDiscoveryCategory);
+        }
+        else
+        {
+            mLogger(Error) << "Unable to register endpoint locator service. Provided component reference is nil";
+        }
     }
 
     void makeReady(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& locator, 
@@ -901,10 +907,6 @@ protected:
 
     UpdateEndpointLocatorRegistryThreadPtr mUpdateThread;
     IceUtil::Time mUpdateInterval;
-
-    //
-    // Stuff we need to find. 
-    //
     EndpointLocatorPrx mProxy;
 
     Ice::ObjectAdapterPtr mObjectAdapter;
diff --git a/test/ComponentTest.cpp b/test/ComponentTest.cpp
index cfd680c..0355d37 100644
--- a/test/ComponentTest.cpp
+++ b/test/ComponentTest.cpp
@@ -21,6 +21,7 @@
 #include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
 #include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
 #include <AsteriskSCF/Configuration/FileSessionGateway/FileSessionGatewayConfigurationIf.h>
+#include <AsteriskSCF/FileSessionGateway/FileSessionGatewayIf.h>
 
 #include <Ice/Ice.h>
 #include <IceBox/IceBox.h>
@@ -37,7 +38,7 @@ using namespace std;
 
 namespace FileMedia = AsteriskSCF::Media::File::V1;
 namespace Media = AsteriskSCF::Media::V1;
-namespace Configuraiton = AsteriskSCF::Configuration::FileSessionGateway::V1;
+namespace Configuration = AsteriskSCF::Configuration::FileSessionGateway::V1;
 
 namespace
 {
@@ -98,9 +99,157 @@ public:
         // 2. Exercise public interfaces.
         // 3. Remove the endpoints.
         //
+
+        AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx configPrx =
+            getGatewayConfiguration();
+
+        BOOST_REQUIRE(configPrx);
+
+        Configuration::GeneralGroupPtr generalGroup = new Configuration::GeneralGroup;
+        Configuration::FileMediaServicePtr mediaService = new Configuration::FileMediaService;
+        mediaService->serviceName =
+            mCommunicator->getProperties()->getPropertyWithDefault("Test.MediaServiceName", "default");
+        generalGroup->configurationItems[Configuration::FileMediaServiceItem] = mediaService;
+
+        AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq configurationData;
+        configurationData.push_back(generalGroup);
+
+        Configuration::EndpointGroupPtr endpointGroup = new Configuration::EndpointGroup;
+        endpointGroup->name = "helloWorld";
+        Configuration::EndpointDestinationNamePtr destinationName = new Configuration::EndpointDestinationName;
+        destinationName->value = "1234";
+        endpointGroup->configurationItems[Configuration::EndpointDestinationItem] = destinationName;
+        Configuration::MediaFilePtr mediaFile = new Configuration::MediaFile;
+        mediaFile->id = "helloWorld.123";
+        mediaFile->operations = AsteriskSCF::Media::File::V1::Playback;
+        endpointGroup->configurationItems[Configuration::EndpointMediaFileItem] = mediaFile;
+        configurationData.push_back(endpointGroup);
+
+        endpointGroup = new Configuration::EndpointGroup;
+        endpointGroup->name = "saveMe";
+        destinationName = new Configuration::EndpointDestinationName;
+        destinationName->value = "9001";
+        endpointGroup->configurationItems[Configuration::EndpointDestinationItem] = destinationName;
+        mediaFile = new Configuration::MediaFile;
+        mediaFile->id = "savedMe.x";
+        mediaFile->operations = AsteriskSCF::Media::File::V1::Recording;
+        endpointGroup->configurationItems[Configuration::EndpointMediaFileItem] = mediaFile;
+        configurationData.push_back(endpointGroup);
+
+        configPrx->setConfiguration(configurationData);
+
+        //
+        // Now, there are a plethora of tests available. We should check the endpoint locator object,
+        // the registry and the validity of any supplied endpoints.
+        //
+        
+        //
+        // Let's start with our endpoint locator.
+        //
+        AsteriskSCF::Core::Routing::V1::EndpointLocatorPrx endpointLocator =
+            getEndpointLocator();
+        BOOST_REQUIRE(endpointLocator);
+
+        AsteriskSCF::Core::Endpoint::V1::EndpointSeq locateResults = endpointLocator->lookup("1234");
+        BOOST_REQUIRE(locateResults.size() == 1);
+        AsteriskSCF::SessionCommunications::V1::SessionEndpointPrx sessionEndpointPrx =
+            AsteriskSCF::SessionCommunications::V1::SessionEndpointPrx::checkedCast(locateResults.front());
+        BOOST_REQUIRE(sessionEndpointPrx);
         
+        AsteriskSCF::SessionCommunications::V1::SessionSeq sessions =
+            sessionEndpointPrx->getSessions();
+        BOOST_REQUIRE(sessions.empty());
+
+        //
+        // Later on we'll do this again, but we'll do it more with listeners and cookies and whatnot.
+        //
+        
+        AsteriskSCF::Core::Routing::V1::LocatorRegistryPrx locatorRegistry =
+            getLocatorRegistry();
+        BOOST_REQUIRE(locatorRegistry);
+
+        locateResults = locatorRegistry->lookup("1234");
+        BOOST_REQUIRE(locateResults.size() == 1);
+        AsteriskSCF::SessionCommunications::V1::SessionEndpointPrx copyOfSessionEndpointPrx =
+            AsteriskSCF::SessionCommunications::V1::SessionEndpointPrx::checkedCast(locateResults.front());
+        BOOST_REQUIRE(copyOfSessionEndpointPrx);
+
+        BOOST_CHECK(copyOfSessionEndpointPrx->ice_getIdentity() == sessionEndpointPrx->ice_getIdentity());
+        BOOST_CHECK(copyOfSessionEndpointPrx == sessionEndpointPrx);
+        sessions = copyOfSessionEndpointPrx->getSessions();
+        BOOST_CHECK(sessions.empty());
     }
 
+    AsteriskSCF::Core::Routing::V1::EndpointLocatorPrx getEndpointLocator()
+    {
+        AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx locator =
+            getServiceLocator();
+        BOOST_REQUIRE(locator);
+        AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr query =
+            new AsteriskSCF::Core::Discovery::V1::ServiceLocatorParams;
+        query->category = AsteriskSCF::FileSessionGateway::V1::EndpointLocatorDiscoveryCategory;
+        query->service = "default";
+        try
+        {
+            Ice::ObjectPrx prx = locator->locate(query);
+            return AsteriskSCF::Core::Routing::V1::EndpointLocatorPrx::checkedCast(prx);
+        }
+        catch (...)
+        {
+            BOOST_FAIL("unable to locate our endpoint locator");
+        }
+        return AsteriskSCF::Core::Routing::V1::EndpointLocatorPrx();
+    }
+
+    AsteriskSCF::Core::Routing::V1::LocatorRegistryPrx getLocatorRegistry()
+    {
+        AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx locator =
+            getServiceLocator();
+        BOOST_REQUIRE(locator);
+        AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr query =
+            new AsteriskSCF::Core::Discovery::V1::ServiceLocatorParams;
+        query->category = AsteriskSCF::Core::Routing::V1::RoutingServiceLocatorRegistryDiscoveryCategory;
+        query->service = "default";
+        try
+        {
+            Ice::ObjectPrx prx = locator->locate(query);
+            return AsteriskSCF::Core::Routing::V1::LocatorRegistryPrx::checkedCast(prx);
+        }
+        catch (...)
+        {
+            BOOST_FAIL("unable to locate our endpoint locator registry");
+        }
+        return AsteriskSCF::Core::Routing::V1::LocatorRegistryPrx();
+    }
+    
+    AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx getServiceLocator()
+    {
+        return AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx::checkedCast(
+            mCommunicator->propertyToProxy("LocatorService.Proxy"));
+    }
+
+    AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx getGatewayConfiguration()
+    {
+        AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx locator =
+            getServiceLocator();
+        BOOST_REQUIRE(locator);
+        AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr query =
+            new AsteriskSCF::Core::Discovery::V1::ServiceLocatorParams;
+        query->category = Configuration::ConfigurationDiscoveryCategory;
+        query->service = "default";
+        try
+        {
+            Ice::ObjectPrx prx = locator->locate(query);
+            return AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx::checkedCast(prx);
+        }
+        catch (...)
+        {
+            BOOST_FAIL("unable to locate configuration service");
+        }
+        return AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx();
+    }
+
+
     //
     // TODO: replica support.
     //

commit 76ae057575c077c85916e9a61b720bcb2f1c4d63
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Dec 2 13:31:50 2011 -0330

    null pointer dereference on oldUpdater.

diff --git a/src/EndpointLocator.cpp b/src/EndpointLocator.cpp
index 3039241..d7d60dc 100644
--- a/src/EndpointLocator.cpp
+++ b/src/EndpointLocator.cpp
@@ -627,7 +627,10 @@ public:
         {
             UniqueLock lock(mLock);
             oldUpdater = mUpdater;
-            oldUpdater->stop();
+            if (oldUpdater)
+            {
+                oldUpdater->stop();
+            }
             
             mUpdater = updater;
             mUpdater->start();

commit 3af7e78132b80618f1b2bd55cb64e881488f6f8e
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Dec 2 13:18:34 2011 -0330

    Fix a.) failure to recognize when and update was completed, b.) race
    condition where an update that occurred while an update was being processed
    would get missed.

diff --git a/src/EndpointLocator.cpp b/src/EndpointLocator.cpp
index adbbbaa..3039241 100644
--- a/src/EndpointLocator.cpp
+++ b/src/EndpointLocator.cpp
@@ -220,6 +220,7 @@ public:
     {
         Monitor::Lock lock(mMonitor);
         mUpdatePending = true;
+        mLastUpdate = IceUtil::Time::now();
         if (!mPaused)
         {
             mMonitor.notify();
@@ -229,7 +230,8 @@ public:
     void run()
     {
         int registrationAttempted = -1;
-        while(!isDone())
+        bool success = false;
+        while(!isDone(success))
         {
             try
             {
@@ -266,6 +268,7 @@ public:
                 {
                     registry->setEndpointLocatorDestinationIds(mRoutingId, mEndpointLocator->getDestinationList());
                 }
+                success = true;
             }
             catch (const LocatorAlreadyRegisteredException&)
             {
@@ -347,24 +350,35 @@ private:
     bool mDone;
     bool mPaused;
     bool mUpdatePending;
+    IceUtil::Time mLastUpdate;
+    IceUtil::Time mLastWake;
     IceUtil::Time mRetryInterval;
     Logger mLogger;
         
     typedef IceUtil::Monitor<IceUtil::Mutex> Monitor;
     Monitor mMonitor;
 
-    bool isDone()
+    bool isDone(bool& success)
     {
         Monitor::Lock lock(mMonitor);
-        if (!mDone)
+        while (!mDone)
         {
-            if (mUpdatePending)
+            if (mPaused)
             {
-                mMonitor.timedWait(mRetryInterval);
+                mMonitor.wait();
             }
             else
             {
-                mMonitor.wait();
+                if (mUpdatePending && !success)
+                {
+                    mMonitor.timedWait(mRetryInterval);
+                }
+                else if (mUpdatePending && mLastUpdate <= mLastWake)
+                {
+                    mMonitor.wait();
+                }
+                mLastWake = mLastUpdate;
+                return mDone;
             }
         }
         return mDone;
@@ -609,8 +623,15 @@ public:
     
     void setUpdaterThread(const UpdateEndpointLocatorRegistryThreadPtr& updater)
     {
-        UniqueLock lock(mLock);
-        mUpdater = updater;
+        UpdateEndpointLocatorRegistryThreadPtr oldUpdater;
+        {
+            UniqueLock lock(mLock);
+            oldUpdater = mUpdater;
+            oldUpdater->stop();
+            
+            mUpdater = updater;
+            mUpdater->start();
+        }
     }
 
     void updateRegistry()
@@ -789,13 +810,15 @@ public:
             mEndpointLocator, mLogger);
         mRegistrationThread->start();
 
+        //
+        // Updater is paused initially.
+        //
         mUpdateThread = new UpdateEndpointLocatorRegistryThread(mLocator, mRegistryParams, mUpdateInterval,
             mEndpointLocator, mRoutingId, false, mLogger);
         
         //
         // This thread will not actually do anything until the endpoint locator gets a configuration update.
         //
-        mUpdateThread->start();
         mEndpointLocator->setUpdaterThread(mUpdateThread);
 
         //

commit 747eac780f3d17274f9eabe07709b36b15742468
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Dec 2 12:51:16 2011 -0330

    Fix issue where the updater thread's pause status did not follow the
    active/standby status of the component.

diff --git a/src/EndpointLocator.cpp b/src/EndpointLocator.cpp
index bad77bd..adbbbaa 100644
--- a/src/EndpointLocator.cpp
+++ b/src/EndpointLocator.cpp
@@ -634,6 +634,14 @@ protected:
         {
             SharedLock lock(mLock);
             copyOfEndpoints = mEndpoints;
+            if (!newReplicatorProxy)
+            {
+                mUpdater->pause();
+            }
+            else
+            {
+                mUpdater->resume();
+            }
         }
         
         for (EndpointMap::const_iterator iter = copyOfEndpoints.begin(); iter != copyOfEndpoints.end(); ++iter)

commit 5bf86c70bfa65017fa77601064a1611b8c4e14ad
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Dec 2 12:45:28 2011 -0330

    - introduce component test
    
    - fix bug found with same, missing updates to the endpoint locator
      registry:
    
      - add updater thread to the endpoint locator servant, when configuration
        alters the endpoints the updater thread wakes up and attempts to update
        the registry. If it fails, it will retry until it succeeds or is told
        to stop

diff --git a/config/file_session_gateway.icebox b/config/file_session_gateway.icebox
index 63b2ea0..8f926b8 100755
--- a/config/file_session_gateway.icebox
+++ b/config/file_session_gateway.icebox
@@ -2,17 +2,63 @@
 # IceBox service configuration file for the file session gateway.
 #
 
-#
-# URN format: category:service[:id[:specific params]]
-#
-# Specify the search criteria for locating the file media service.
-#
-DefaultFileMediaService=astscf:filemedia:defaultfilemedia
-
+# All services loaded by this configuration file should also load these
+# properties.
 Ice.InheritProperties=1
+
+# 
+# Standard defaults.
+#
 LocatorService.Proxy=LocatorService:default -p 4411
 LocatorServiceManagement.Proxy=LocatorServiceManagement:default -p 4422
 Ice.ThreadPool.Client.Size=4
+Ice.ThreadPool.Server.Size=4
+
 
+#
+# Load the gateway.
+#
 IceBox.Service.FileSessionGateway=FileSessionGateway:create
+FileSessionGateway.ServiceAdapter.Endpoints=default -p 5121
+FileSessionGateway.ServiceAdapter.ThreadPool.Size=5
+FileSessionGateway.BackplaneAdapter.Endpoints=default -p 5122
+FileSessionGateway.BackplaneAdapter.ThreadPool.Size=4
+
+#
+# FileSessionGateway configuration properties.
+#
+
+# RoutingDestinationId :
+#
+# Set the string that the Endpoint locator will use to register itself with
+# the locator registry. While this defaults to 'component name'.fileSessionGateway,
+# where component name is derived from how the component's IceBox service
+# is configured, it is advisable to set a non-default value to prevent
+# trivial un-related changes to configuration from upsetting the validitiy
+# of as system, particularly in systems involving replication.
+#
+# FileSessionGateway.RoutingDestinationId=[string value]
+
+
+#
+# LocatorRegistry.SetupRetryInterval:
+#
+# Controls the retry period interval for registering an endpoint locator
+# with the locator registry. The value is in milliseconds and the default
+# value is 5000ms (5 seconds). This value affects the startup interaction
+# with another component, in effect altering how "nice" the service handles
+# out of order component startup. The syntax is 'component
+# name'.LocatorRegistry.SetupRetryInterval.
+#
+# FileSessionGateway.LocatorRegistry.SetupRetryInterval=[positive integer value, milliseconds]
+
+#
+# LocatorRegistry.UpdateRetryInterval
+#
+# Similar to SetupRetryInterval, this millisecond retry period
+# configures how long the component waits between attempts to update
+# the locator registry with changes to the configured endpoints.
+#
+
+
 
diff --git a/config/test_file_session_gateway.icebox b/config/test_file_session_gateway.icebox
new file mode 100644
index 0000000..8d6720a
--- /dev/null
+++ b/config/test_file_session_gateway.icebox
@@ -0,0 +1,83 @@
+#
+# IceBox service configuration file for the file session gateway.
+#
+
+# All services loaded by this configuration file should also load these
+# properties.
+Ice.InheritProperties=1
+
+#
+# Some APIs are generated as AMD and some internal calls may use AMI, both
+# of which will fail if collocation optimization is used. Turn it off.
+#
+Ice.Default.CollocationOptimized=0
+
+# 
+# Standard defaults.
+#
+LocatorService.Proxy=LocatorService:default -p 4411
+LocatorServiceManagement.Proxy=LocatorServiceManagement:default -p 4422
+Ice.ThreadPool.Client.Size=4
+Ice.ThreadPool.Server.Size=4
+
+LoggerAdapter.Endpoints=default
+Logger.ServiceAdapter.Endpoints=default
+AsteriskSCF.LoggingService.Endpoints=default
+AsteriskSCF.LoggingService.ThreadPool.Size=4
+AsteriskSCF.LoggingClient.Endpoints=default
+AsteriskSCF.LoggingClient.ThreadPool.Size=4
+
+ServiceDiscovery.IceStorm.TopicManager.Endpoints=default -p 4421
+ServiceDiscovery.IceStorm.TopicManager.ThreadPool.Size=4
+ServiceDiscovery.IceStorm.InstanceName=ServiceDiscovery
+ServiceDiscovery.IceStorm.Publish.Endpoints=tcp -p 10001:udp -p 10001
+ServiceDiscovery.IceStorm.Publish.ThreadPool.Size=4
+ServiceDiscovery.IceStorm.Transient=1
+ServiceDiscovery.IceStorm.Trace.TopicManager=0
+ServiceDiscovery.IceStorm.Flush.Timeout=2000
+TopicManager.Proxy=ServiceDiscovery/TopicManager:default -p 4421
+
+ServiceDiscovery.BackplaneAdapter.Endpoints=default -p 4410
+ServiceDiscovery.BackplaneAdapter.ThreadPool.Size=4
+ServiceDiscovery.Locator.ServiceAdapter.Endpoints=default -p 4411
+ServiceDiscovery.Locator.ServiceAdapter.ThreadPool.Size=4
+ServiceDiscovery.Management.ServiceAdapter.Endpoints=default -p 4422
+ServiceDiscovery.Management.ServiceAdapter.ThreadPool.Size=4
+
+BridgeService.BridgeManagerObjectId=TestBridge
+BridgeService.Standalone=true
+BridgeService.ServiceAdapter.Endpoints=default -p 57000
+BridgeService.ServiceAdapter.ThreadPool.Size=4
+BridgeService.BackplaneAdapter.Endpoints=default -p 57001
+BridgeService.BackplaneAdapter.ThreadPool.Size=4
+
+RoutingService.ServiceAdapter.Endpoints=default -p 10050
+RoutingService.ServiceAdapter.ThreadPool.Size=4
+RoutingService.Stanadlone=true
+RoutingService.BackplaneAdapter.Endpoints=default -p 10051
+
+FileSessionGateway.ServiceAdapter.Endpoints=default -p 58001
+FileSessionGateway.ServiceAdapter.ThreadPool.Size=4
+FileSessionGateway.BackplaneAdapter.Endpoints=default -p 58002
+FileSessionGateway.BackplaneAdapter.ThreadPool.Size=4
+
+#
+# Load the ancillary componnents
+#
+IceBox.Service.Logger=logging-service:createLoggingService
+IceBox.Service.Replicator=FileSessionGatewayReplicator:create
+IceBox.Service.RoutingService=BasicRoutingService:create
+IceBox.Service.BridgeService=bridgeservice:create
+IceBox.Service.ServiceDiscovery=service_locator:create
+
+#
+# Load the gateway and the tester.
+#
+IceBox.Service.FileSessionGateway=FileSessionGateway:create
+IceBox.Service.GatewayTester=FileSessionGatewayTest:create
+
+IceBox.LoadOrder=ServiceDiscovery Logger BridgeService RoutingService Replicator FileSessionGateway GatewayTester
+
+IceBox.ServiceManager.Endpoints=default -p 56000
+IceBox.ServiceManager.ThreadPool.Size=4
+IceBoxMgr.Proxy=IceBox/ServiceManager:default -p 56000
diff --git a/src/EndpointLocator.cpp b/src/EndpointLocator.cpp
index 4a5a9fd..bad77bd 100644
--- a/src/EndpointLocator.cpp
+++ b/src/EndpointLocator.cpp
@@ -40,6 +40,13 @@ namespace FileSessionGtw
 {
 
 //
+// TODO/BUG: Okay, so there is a bug where the locator registry isn't
+// getting updated properly.  While AMI would work for most situations, we
+// may as well reuse the RegisterEndpointLocator thread implementation
+// since it is robust in ConnectionLostException situations.
+//
+
+//
 // TODO: thread pool
 //
 class RegisterEndpointLocator : public IceUtil::Thread
@@ -185,6 +192,187 @@ private:
 };
 typedef IceUtil::Handle<RegisterEndpointLocator> RegisterEndpointLocatorPtr;
 
+class UpdateEndpointLocatorRegistryThread : public IceUtil::Thread
+{
+public:
+    
+    UpdateEndpointLocatorRegistryThread(
+        const ServiceLocatorPrx& locator,
+        const ServiceLocatorParamsPtr& query,
+        const IceUtil::Time& retryInterval,
+        const EndpointLocatorImplPtr& endpointLocator,
+        const string& routingId,
+        bool paused,
+        const Logger& logger) :
+        mLocator(locator),
+        mQuery(query),
+        mEndpointLocator(endpointLocator),
+        mRoutingId(routingId),
+        mDone(false),
+        mPaused(paused),
+        mUpdatePending(false),
+        mRetryInterval(retryInterval),
+        mLogger(logger)
+    {
+    }
+        
+    void update()
+    {
+        Monitor::Lock lock(mMonitor);
+        mUpdatePending = true;
+        if (!mPaused)
+        {
+            mMonitor.notify();
+        }
+    }
+    
+    void run()
+    {
+        int registrationAttempted = -1;
+        while(!isDone())
+        {
+            try
+            {
+                Ice::ObjectPrx prx; 
+                try
+                {
+                    prx = mLocator->locate(mQuery);
+                    
+                    //
+                    // The locator is supposed to throw an exception if it fails. A nil proxy is bad.
+                    //
+                    assert(prx); 
+                }
+                catch (const std::exception& ex)
+                {
+                    mLogger(Warning) << "Attempt to locate the endpoint locator registry failed with: " << ex.what();
+                    continue;
+                }
+                catch (...)
+                {
+                    mLogger(Warning) << "Attempt to locate the endpoint locator registry failed with an unknown "
+                        "exception";
+                    throw;
+                }
+                LocatorRegistryPrx registry = LocatorRegistryPrx::checkedCast(prx);
+                if (registrationAttempted == 0)
+                {
+                    registry->addEndpointLocator(mRoutingId, mEndpointLocator->getDestinationList(), 
+                        mEndpointLocator->getProxy());
+                    mLogger(Info) << "Endpoint locator successfully registered with endpoint locator registry";
+                    ++registrationAttempted;
+                }
+                else
+                {
+                    registry->setEndpointLocatorDestinationIds(mRoutingId, mEndpointLocator->getDestinationList());
+                }
+            }
+            catch (const LocatorAlreadyRegisteredException&)
+            {
+                mLogger(Error) << "Caught a LocatorAlreadyRegisteredException when attempting to resolve "
+                    "an unexpected condition. This will not be re-attempted and indicates a possible system-wide "
+                    "configuration. This update is cancelled.";
+                cancelUpdate();
+            }
+            catch (const DestinationNotFoundException&)
+            {
+                mLogger(Warning) << "Caught a DestinationNotFoundException while updating the endpoint "
+                    "locator registry. Assuming some sort of race condition during startup, so a registration "
+                    "attempt will occur";
+                ++registrationAttempted;
+            }
+            catch (const InvalidParamsException&)
+            {
+                mLogger(Error) << "Caught an InvalidParamsException while updating the endpoint locator registry, "
+                    "there appears to be some problem with our endpoint list or the compatability with the registry. "
+                    "Please check your configuration and/or contact your system administrator.";
+            }
+            catch (const Ice::SyscallException& ex)
+            {
+                mLogger(Warning) << "Caught exception (" << ex.what() << ") while attempting to contact the "
+                    "endpoint locator registry, retrying";
+            }
+            catch (const Ice::ObjectNotExistException&)
+            {
+                mLogger(Warning) << "Caught an ONE while attempting to contact the endpoint locator registry, "
+                    "will continue retrying in the event that this is a configuration issue/bug in setup.";
+            }
+            catch (const std::exception& ex)
+            {
+                mLogger(Error) << "Caught an unexpected exception (" << ex.what() << ") "
+                    "when attempting to contact the endpoint "
+                    "locator registry. We will continue retrying, but this service should be shutdown until "
+                    "the source of the problem is located and resolved.";
+            }
+            catch (...)
+            {
+                mLogger(Error) << "Caught an unknown exception when attempting to contact the endpoint "
+                    "locator registry. We will continue retrying, but this service should be shutdown until "
+                    "the source of the problem is located and resolved.";
+            }
+        }
+    }
+    
+    void pause()
+    {
+        Monitor::Lock lock(mMonitor);
+        mPaused = true;
+    }
+        
+    void resume()
+    {
+        Monitor::Lock lock(mMonitor);
+        mPaused = false;
+        mMonitor.notify();
+    }
+    
+    void stop()
+    {
+        Monitor::Lock lock(mMonitor);
+        mDone = true;
+        mMonitor.notify();
+    }
+
+    void cancelUpdate()
+    {
+        Monitor::Lock lock(mMonitor);
+        mUpdatePending = false;
+    }
+
+private:
+    ServiceLocatorPrx mLocator;
+    ServiceLocatorParamsPtr mQuery;
+    EndpointLocatorImplPtr mEndpointLocator;
+    string mRoutingId;
+    bool mDone;
+    bool mPaused;
+    bool mUpdatePending;
+    IceUtil::Time mRetryInterval;
+    Logger mLogger;
+        
+    typedef IceUtil::Monitor<IceUtil::Mutex> Monitor;
+    Monitor mMonitor;
+
+    bool isDone()
+    {
+        Monitor::Lock lock(mMonitor);
+        if (!mDone)
+        {
+            if (mUpdatePending)
+            {
+                mMonitor.timedWait(mRetryInterval);
+            }
+            else
+            {
+                mMonitor.wait();
+            }
+        }
+        return mDone;
+    }
+};
+
+typedef IceUtil::Handle<UpdateEndpointLocatorRegistryThread> UpdateEndpointLocatorRegistryThreadPtr;
+
 const string EndpointIdPrefix("asteriskscf.file_session_gateway.endpoint.");
 
 class EndpointLocatorServant : public EndpointLocatorImpl
@@ -268,6 +456,7 @@ public:
                 //
             }
         }
+        updateRegistry();
     }
 
     void removeEndpoints(const EndpointSpecificationSeq& endpoints)
@@ -343,6 +532,7 @@ public:
         {
             (*iter)->destroy();
         }
+        updateRegistry();
     }
 
     RegExSeq getDestinationList() 
@@ -392,6 +582,8 @@ public:
     {
         {
             UniqueLock lock(mLock);
+            mUpdater->stop();
+            mUpdater = 0;
             if (isDestroyed())
             {
                 return;
@@ -414,6 +606,21 @@ public:
     {
         return ReplicationAdapterPtr();
     }
+    
+    void setUpdaterThread(const UpdateEndpointLocatorRegistryThreadPtr& updater)
+    {
+        UniqueLock lock(mLock);
+        mUpdater = updater;
+    }
+
+    void updateRegistry()
+    {
+        SharedLock lock(mLock);
+        if (mUpdater)
+        {
+            mUpdater->update();
+        }
+    }
 
 protected:
     void onProxyUpdate()
@@ -453,6 +660,7 @@ private:
     string mId;
     RemoteServicesPtr mRemoteServices;
     EndpointLocatorPrx mProxy;
+    UpdateEndpointLocatorRegistryThreadPtr mUpdater;
 
     bool mDestroyed;
 
@@ -490,7 +698,11 @@ public:
         mProxy = EndpointLocatorPrx::uncheckedCast(mObjectAdapter->add(mEndpointLocator, id));
         mRetryInterval = IceUtil::Time::milliSeconds(
             mObjectAdapter->getCommunicator()->getProperties()->getPropertyAsIntWithDefault(
-                "FileSessionGateway.SetupRetryInterval", 5000)
+                mComponentId + ".LocatorRegistry.SetupRetryInterval", 5000)
+            );
+        mUpdateInterval = IceUtil::Time::milliSeconds(
+            mObjectAdapter->getCommunicator()->getProperties()->getPropertyAsIntWithDefault(
+                mComponentId + ".LocatorRegistry.UpdateRetryInterval", 5000)
             );
         mEndpointLocator->setProxy(mProxy);
         return mProxy;
@@ -565,13 +777,19 @@ public:
         mLogger(Info) << "As we failed to get the endpoint locator registry and register ourselves, we are going "
             "to go into retry mode";
             
-        //
-        // TODO: make retry configurable.
-        //
         mRegistrationThread = new RegisterEndpointLocator(mLocator, mRegistryParams, mRoutingId, mRetryInterval, 
             mEndpointLocator, mLogger);
         mRegistrationThread->start();
 
+        mUpdateThread = new UpdateEndpointLocatorRegistryThread(mLocator, mRegistryParams, mUpdateInterval,
+            mEndpointLocator, mRoutingId, false, mLogger);
+        
+        //
+        // This thread will not actually do anything until the endpoint locator gets a configuration update.
+        //
+        mUpdateThread->start();
+        mEndpointLocator->setUpdaterThread(mUpdateThread);
+
         //
         // TODO: So where do we kill the thread if things have gone wrong and we want to give up?
         //
@@ -590,6 +808,10 @@ public:
             mRegistrationThread->stop();
             mRegistrationThread = 0;
         }
+        if (mUpdateThread)
+        {
+            mUpdateThread->pause();
+        }
         Ice::ObjectPrx prx;
         try
         {
@@ -641,7 +863,10 @@ protected:
     // Our own stuff.
     //
     RegisterEndpointLocatorPtr mRegistrationThread;
-    IceUtil::Time mRetryInterval;     // Oh, and btw... we will probably want to configure this. <= TODO
+    IceUtil::Time mRetryInterval;
+
+    UpdateEndpointLocatorRegistryThreadPtr mUpdateThread;
+    IceUtil::Time mUpdateInterval;
 
     //
     // Stuff we need to find. 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f72f87f..6416a63 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -50,3 +50,12 @@ astscf_component_add_boost_libraries(FileSessionGatewayEndpointLocatorTest unit_
 astscf_component_build_standalone(FileSessionGatewayEndpointLocatorTest)
 target_link_libraries(FileSessionGatewayEndpointLocatorTest logging-client astscf-ice-util-cpp)
 astscf_test_boost(FileSessionGatewayEndpointLocatorTest)
+
+astscf_component_init(FileSessionGatewayTest)
+astscf_component_add_slices(FileSessionGatewayTest LOCAL TestCookiesIf.ice)
+astscf_component_add_files(FileSessionGatewayTest ComponentTest.cpp)
+astscf_component_add_slice_collection_libraries(FileSessionGatewayTest FILESESSIONGATEWAY ASTSCF)
+astscf_component_add_boost_libraries(FileSessionGatewayTest unit_test_framework thread)
+astscf_component_build_icebox(FileSessionGatewayTest)
+target_link_libraries(FileSessionGatewayTest logging-client astscf-ice-util-cpp)
+astscf_test_icebox(FileSessionGatewayTest config/test_file_session_gateway.icebox)
diff --git a/test/ComponentTest.cpp b/test/ComponentTest.cpp
new file mode 100644
index 0000000..cfd680c
--- /dev/null
+++ b/test/ComponentTest.cpp
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+#include "TestCookiesIf.h"
+
+#include <AsteriskSCF/Media/File/FileMediaIf.h>
+#include <AsteriskSCF/Media/MediaIf.h>
+#include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
+#include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
+#include <AsteriskSCF/Configuration/FileSessionGateway/FileSessionGatewayConfigurationIf.h>
+
+#include <Ice/Ice.h>
+#include <IceBox/IceBox.h>
+#include <IceUtil/UUID.h>
+
+#include <boost/bind.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/debug.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+
+using namespace AsteriskSCF::SessionCommunications::V1;
+using namespace std;
+
+namespace FileMedia = AsteriskSCF::Media::File::V1;
+namespace Media = AsteriskSCF::Media::V1;
+namespace Configuraiton = AsteriskSCF::Configuration::FileSessionGateway::V1;
+
+namespace
+{
+
+const string TestAdapterName = "GatewayTestAdapter";
+
+/**
+ * Helper function that sets a property if it is not already set. Good for
+ * providing defaults to the Ice runtime.
+ */
+void propertyGetSet(const Ice::PropertiesPtr& properties, const string& propertyName,
+    const string& value)
+{
+    properties->setProperty(propertyName, properties->getPropertyWithDefault(propertyName, value));
+}
+
+class FileSessionGatewaySuite : public boost::enable_shared_from_this<FileSessionGatewaySuite>
+{
+public:
+    FileSessionGatewaySuite(const Ice::CommunicatorPtr& communicator, const Ice::StringSeq& args):
+        mCommunicator(communicator),
+        mArgs(args),
+        mArgv(0)
+    {
+        mArgs.insert(mArgs.begin(), "FileSessionGatewayTest");
+        for (Ice::StringSeq::const_iterator argIter = mArgs.begin(); argIter != mArgs.end(); ++argIter)
+        {
+            mArgv.push_back(argIter->c_str());
+        }
+        mArgv.push_back((const char*)0);
+
+        Ice::PropertiesPtr currentProperties = mCommunicator->getProperties();
+        propertyGetSet(currentProperties, TestAdapterName + ".ThreadPool.Size", "4");
+        propertyGetSet(currentProperties, TestAdapterName + ".Endpoints", "default");
+    }
+
+    size_t argc()
+    {
+        return mArgv.size();
+    }
+
+    char** argv()
+    {
+        return (char**)&mArgv[0];
+    }
+
+    Ice::CommunicatorPtr communicator()
+    {
+        return mCommunicator;
+    }
+
+    void endpointLocatorTest()
+    {
+        //
+        // Steps to the test:
+        // 1. Configure some endpoints (so yes there is some testing of configuration in here, there
+        // isn't a programmatic way to directly add endpoints).
+        // 2. Exercise public interfaces.
+        // 3. Remove the endpoints.
+        //
+        
+    }
+
+    //
+    // TODO: replica support.
+    //
+protected:
+    Ice::CommunicatorPtr mCommunicator;
+    Ice::StringSeq mArgs;
+    vector<const char*> mArgv;
+};
+typedef boost::shared_ptr<FileSessionGatewaySuite> TestSuitePtr;
+
+using namespace boost::unit_test;
+
+TestSuitePtr GatewayTest;
+
+bool init_unit_test()
+{
+    framework::master_test_suite().add(
+        BOOST_TEST_CASE(boost::bind(&FileSessionGatewaySuite::endpointLocatorTest, GatewayTest)));
+}
+
+
+class TestRunner : public IceUtil::Thread
+{
+public:
+    TestRunner(const TestSuitePtr& suite) :
+        mSuite(suite)
+    {
+    }
+    
+    void run()
+    {
+        int argc = (int)mSuite->argc();
+        char** argv = mSuite->argv();
+        int result = boost::unit_test::unit_test_main(&init_unit_test, argc, argv);
+        exit(result);
+
+        Ice::InitializationData initializationData;
+        initializationData.properties = mSuite->communicator()->getProperties();
+        Ice::CommunicatorPtr shutdownCommunicator = Ice::initialize(initializationData);
+        try
+        {
+            IceBox::ServiceManagerPrx manager = IceBox::ServiceManagerPrx::checkedCast(
+                shutdownCommunicator->propertyToProxy("IceBoxMgr.Proxy"));
+            if (manager)
+            {
+                manager->shutdown();
+            }
+        }
+        catch (...)
+        {
+            //
+            // not much to happen here... we tried.
+            //
+        }
+    }
+    
+private:
+    TestSuitePtr mSuite;
+};
+typedef IceUtil::Handle<TestRunner> TestRunnerPtr;
+
+class GatewayTester : public IceBox::Service
+{
+public:
+    ~GatewayTester()
+    {
+    }
+
+    void start(const string&, const Ice::CommunicatorPtr& communicator, const Ice::StringSeq& args)
+    {
+        GatewayTest.reset(new FileSessionGatewaySuite(communicator, args));
+        mTestRunner = new TestRunner(GatewayTest);
+        mTestRunner->start();
+    }
+
+    void stop()
+    {
+        //
+        // Not much we can do here.
+        //
+    }
+
+protected:
+    TestRunnerPtr mTestRunner;
+};
+}
+
+extern "C"
+{
+    ASTSCF_DLL_EXPORT ::IceBox::Service* create(Ice::CommunicatorPtr)
+    {
+        return new GatewayTester;
+    }
+}
diff --git a/test/TestEndpointLocator.cpp b/test/TestEndpointLocator.cpp
index aededdb..27c592b 100644
--- a/test/TestEndpointLocator.cpp
+++ b/test/TestEndpointLocator.cpp
@@ -16,7 +16,7 @@
 
 /**
  *
- * This test drive is very "unit testing" oriented. With very direct
+ * This test driver is very "unit testing" oriented. With very direct
  * exercising of interfaces. No collateral services are employed by these
  * tests, so it may be run standalone.
  *
diff --git a/test/TestSessionObject.cpp b/test/TestSessionObject.cpp
index a91713c..40c9cb0 100644
--- a/test/TestSessionObject.cpp
+++ b/test/TestSessionObject.cpp
@@ -16,7 +16,7 @@
 
 /**
  *
- * This test drive is very "unit testing" oriented. With very direct
+ * This test driver is very "unit testing" oriented. With very direct
  * exercising of interfaces. No collateral services are employed by these
  * tests, so it may be run standalone.
  *

commit d7821023155078488fc3f0815ac7883f9c778138
Author: Brent Eagles <beagles at digium.com>
Date:   Thu Dec 1 18:14:04 2011 -0330

    - Add general group to configurator script and fix dictionary names to use
      variables specificied in Slice.
    
    - Passing endpoint specification into session for information required when
      creating media session (data is cloned so there is no backwards
      dependency on the endpoint)
    
    - Fix up sample configuration file and add documentation/comments
    
    - Keep unit test up to date with changing signatures.

diff --git a/config/FileSessionGateway.config b/config/FileSessionGateway.config
index a72191a..b48c334 100755
--- a/config/FileSessionGateway.config
+++ b/config/FileSessionGateway.config
@@ -2,5 +2,46 @@
 # A sample configuration file for the FileSessionGateway
 #
 
+#
+# General configuration group is used to set component wide configurable properties.
+#
 [general]
-endpoint-locator-id=basic.filesession.gtw
\ No newline at end of file
+routing_service=default
+media_service=default
+
+##
+## Anatomy of an endpoint specification.
+##
+## The name of the endpoint is derived from the section name.
+# [endpoint-name]
+#
+## The following line is required by the configuration script so that it
+## recognizes this as an endpoint configuration
+# type=endpoint
+#
+## supported_operations describes whether the endpoint is meant to support
+## recording, playback or both. The valid values are: recording, playback, both
+#
+# supported_operations=playback
+#
+## media_id is a string that specifies the catalog id for media, this
+## is a string that is used when querying the file media service for a
+## media session. Multiple endpoints may contain the same media_id. Valid
+## values are deployment dependent.
+#
+# media_id=X13A4AB.ADDA.AF
+#
+## destination is a string that is published by the file session
+## gateway as the number/destination for this endpoint. Once
+## registered with an endpoint locator, calls routed to this value
+## should result in a session being created on the endpoint.
+#
+# destination=1234
+#
+# e.g.:
+
+[hello_world]
+type=endpoint
+supported_operations=playback
+media_id=helloWorld
+destination=7777
\ No newline at end of file
diff --git a/config/FileSessionGatewayConfigurator.py b/config/FileSessionGatewayConfigurator.py
index e5f8966..766cce8 100755
--- a/config/FileSessionGatewayConfigurator.py
+++ b/config/FileSessionGatewayConfigurator.py
@@ -31,7 +31,17 @@ class SectionVisitors(Configurator.SectionVisitors):
     def visit_general_group(self, config, section):
         group = AsteriskSCF.Configuration.FileSessionGateway.V1.GeneralGroup()
         group.configurationItems = { }
-        # no current configuration items.
+
+        mapper = Configurator.OptionMapper()
+        item = AsteriskSCF.Configuration.FileSessionGateway.V1.RoutingService()
+        mapper.map('routing_service', item, 'serviceName',
+                   AsteriskSCF.Configuration.FileSessionGateway.V1.RoutingServiceItem, config.get, "default")
+        item = AsteriskSCF.Configuration.FileSessionGateway.V1.FileMediaService()
+        mapper.map('media_service', item, 'serviceName',
+                   AsteriskSCF.Configuration.FileSessionGateway.V1.FileMediaServiceItem(), config.get, "default");
+        for option in config.options(section):
+            mapper.execute(group, section, option)
+        mapper.finish()
         self.groups.append(group)
         
     def visit_endpoint_group(self, config, section):
@@ -39,6 +49,7 @@ class SectionVisitors(Configurator.SectionVisitors):
         # setup endpoint group.
         #
         group = AsteriskSCF.Configuration.FileSessionGateway.V1.EndpointGroup()
+        group.name = section
         group.configurationItems = { }
 
         #
@@ -58,17 +69,24 @@ class SectionVisitors(Configurator.SectionVisitors):
 
         mapper = Configurator.OptionMapper()
         item = AsteriskSCF.Configuration.FileSessionGateway.V1.EndpointDestinationName()
-        mapper.map('destination', item, 'destination', 'destination', config.get, None)
+        mapper.map('destination', item, 'destination',
+                   AsteriskSCF.Configuration.FileSessionGateway.V1.EndpointDestinationItem, config.get, None)
         item = AsteriskSCF.Configuration.FileSessionGateway.V1.MediaFile()
-        mapper.map('media_id', item, 'id', 'mediaFile', config.get, None)
+        mapper.map('media_id', item, 'id',
+                   AsteriskSCF.Configuration.FileSessionGateway.V1.EndpointMediaFileItem, config.get, None)
         fileOpTransformer = FileOperationTransformer(config)
-        mapper.map('supported_operations', item, 'operations', 'mediaFile', fileOpTransformer.get,
+        mapper.map('supported_operations', item, 'operations',
+                   AsteriskSCF.Configuration.FileSessionGateway.V1.EndpointMediaFileItem, fileOpTransformer.get,
                    AsteriskSCF.Media.File.V1.FileOperations.Playback)
         for option in config.options(section):
             mapper.execute(group, section, option)
         mapper.finish(group)
         self.groups.append(group)
 
+    def visit_unsupported(self, config, section):
+        if config.get(section, 'type') == 'endpoint':
+            self.visit_endpoint_group(config, section)
+            
 # In order to do service locator based lookup we need to pass in a params object
 serviceLocatorParams = AsteriskSCF.Core.Discovery.V1.ServiceLocatorParams()
 serviceLocatorParams.category = AsteriskSCF.Configuration.SipSessionManager.V1.ConfigurationDiscoveryCategory
diff --git a/src/Endpoint.cpp b/src/Endpoint.cpp
index 26970fa..d99623b 100644
--- a/src/Endpoint.cpp
+++ b/src/Endpoint.cpp
@@ -133,7 +133,7 @@ public:
             UniqueLock lock(mLock);
             SessionImplActivation activation;
             activation.servant = SessionImpl::create(mLocator, realProxy, mPublicProxy, baseId,
-                mSpecification->id, mRemoteServices, mAdapter, mLogger);
+                mSpecification->id, getSpecification(), mRemoteServices, mAdapter, mLogger);
             activation.proxy = SessionPrx::uncheckedCast(mAdapter->add(activation.servant, id));
             newProxy = activation.proxy;
 
@@ -532,7 +532,7 @@ ReplicationAdapterPtr EndpointServant::createSessionReplica(
     //
     
     SessionImplPtr sessionServant = SessionImpl::create(mLocator, sessionState, otherStateItems,
-        mPublicProxy, mRemoteServices, mAdapter, mLogger);
+        mPublicProxy, getSpecification(), mRemoteServices, mAdapter, mLogger);
     SessionImplActivation activation;
     activation.servant = sessionServant;
     activation.proxy = SessionPrx::uncheckedCast(mAdapter->add(activation.servant, sessionState->sessionObjectId));
diff --git a/src/Session.cpp b/src/Session.cpp
index 74e0707..6ff4bf0 100644
--- a/src/Session.cpp
+++ b/src/Session.cpp
@@ -36,6 +36,7 @@ namespace AsteriskSCF
 namespace FileSessionGtw
 {
 
+namespace FileMedia = AsteriskSCF::Media::File::V1;
 namespace Media = AsteriskSCF::Media::V1;
 namespace Replication = AsteriskSCF::Replication::FileSessionGateway::V1;
 
@@ -74,6 +75,7 @@ public:
         const SessionEndpointPrx& myEndpointProxy,
         const string& id,
         const string& endpointKey,
+        const EndpointSpecificationPtr& spec,
         const RemoteServicesPtr& remoteServices,
         const Ice::ObjectAdapterPtr& adapter, 
         const Logger& logger) :
@@ -83,13 +85,15 @@ public:
         mPublicProxy(myPublicProxy),
         mParentEndpoint(myEndpointProxy),
         mEndpointKey(endpointKey),
+        mSpecification(spec),
         mRemoteServices(remoteServices),
         mDestroyed(false),
         mId(id),
         mLogger(logger),
         mStartTime(new AsteriskSCF::System::Time::V1::TimeMarker),
         mConnectionStart(0),
-        mCurrentState("pending")
+        mCurrentState("pending"),
+        mStarted(false)
     {
         mCookieManager.reset(new CookieManager(CookieManagerListenerPtr(new CookieManagerCallbackAdapter(this))));
         mLogger(Trace) << "new Session object created (" << mId << ")";
@@ -174,7 +178,7 @@ public:
     }
 
     void indicate_async(const AMD_Session_indicatePtr& cb, const IndicationPtr& indication, const
-        Ice::Current&)
+        Ice::Current& current)
     {
         try
         {
@@ -185,7 +189,8 @@ public:
 
                 //
                 // Start playback/recording if not already started.
-                // 
+                //
+                start(current);
             }
             {
                 FlashIndicationPtr flash = FlashIndicationPtr::dynamicCast(indication);
@@ -320,17 +325,83 @@ public:
 
     void start(const Ice::Current&)
     {
-        UniqueLock lock(mLock);
-        stateCheckNoLock();
-        mConnectionStart = time(0);
-        mCurrentState = "started";
+        FileMedia::FileMediaServicePrx mediaService =
+            mRemoteServices->getMediaService();
+        {
+            UniqueLock lock(mLock);
+            stateCheckNoLock();
+            if (mStarted)
+            {
+                return;
+            }
+            mConnectionStart = time(0);
+            mCurrentState = "started";
+            mStarted = true;
+        }
+
+        FileMedia::FileMediaSpecification spec;
+        spec.supportedOperations = mSpecification->operations;
+        spec.catalogID = mSpecification->mediaFile;
+
+        FileMedia::FileSessionPrx newSession;
+        try
+        {
+            newSession = mediaService->create(spec);
+            {
+                UniqueLock lock(mLock);
+                mMediaSession = newSession;
+            }
+            newSession->start();
+            return;
+        }
+        catch (const FileMedia::FileOperationNotAvailable&)
+        {
+            mLogger(Error) << "Unable to start session, the requested file operation is not supported "
+                "for " << mSpecification->mediaFile;
+        }
+        catch (const FileMedia::UnknownCatalogID&)
+        {
+            mLogger(Error) << "Unable to start session, " << mSpecification->mediaFile <<
+                " is not available at the configured file media service.";
+        }
+        catch (const FileMedia::ResourceUnavailable& ex)
+        {
+            mLogger(Error) << "Unable to start session, resource is unavailable " << ex.message;
+        }
+        //
+        // By rights, there should be some kind of exception here.
+        //
     }
 
     void stop(const ResponseCodePtr&, const Ice::Current&)
     {
-        UniqueLock lock(mLock);
-        stateCheckNoLock();
-        mCurrentState = "stopped";
+        FileMedia::FileSessionPrx fileSession;
+        {
+            UniqueLock lock(mLock);
+            stateCheckNoLock();
+            mCurrentState = "stopped";
+            if (!mStarted)
+            {
+                return;
+            }
+            fileSession = mMediaSession;
+            mMediaSession = FileMedia::FileSessionPrx();
+        }
+        if (fileSession)
+        {
+            try
+            {
+                fileSession->release();
+            }
+            catch (const Ice::Exception& ex)
+            {
+                mLogger(Error) << ex.what() << " received when releasing file media session";
+            }
+            catch (...)
+            {
+                mLogger(Error) << "Received an unknown exception when releaseing file session";
+            }
+        }
     }
 
     void getBridge_async(const AMD_Session_getBridgePtr& cb, const Ice::Current&)
@@ -385,6 +456,9 @@ public:
     void removeBridge_async(const AMD_Session_removeBridgePtr& cb, const SessionListenerPrx& listener,
         const Ice::Current&)
     {
+        //
+        // TODO: Should the removal from the bridge result in a pause on the associated media session.
+        //
         try
         {
             Replication::BridgeStatePtr stateUpdate;
@@ -729,6 +803,7 @@ private:
     CookieManagerPtr mCookieManager;
     SessionEndpointPrx mParentEndpoint;
     string mEndpointKey;
+    EndpointSpecificationPtr mSpecification;
     RemoteServicesPtr mRemoteServices;
     bool mDestroyed;
     string mId;
@@ -736,10 +811,11 @@ private:
     SessionInfoPtr mInfo;
     BridgePrx mBridge;
     SessionControllerPrx mSessionController;
-    Media::SessionPrx mMediaSession;
+    FileMedia::FileSessionPrx mMediaSession;
     AsteriskSCF::System::Time::V1::TimeMarkerPtr mStartTime;
     long mConnectionStart;
     string mCurrentState;
+    bool mStarted;
 
     void stateCheck()
     {
@@ -866,11 +942,13 @@ SessionImplPtr SessionImpl::create(
     const SessionEndpointPrx& myEndpointProxy,
     const string& id,
     const string& endpointId,
+    const EndpointSpecificationPtr& endpointSpec,
     const RemoteServicesPtr& remoteServices,
     const Ice::ObjectAdapterPtr& adapter,
     const Logger& logger)
 {
-    return new SessionServant(locator, myProxy, myEndpointProxy, id, endpointId, remoteServices, adapter, logger);
+    return new SessionServant(locator, myProxy, myEndpointProxy, id, endpointId, endpointSpec, remoteServices,
+        adapter, logger);
 }
 
 SessionImplPtr SessionImpl::create(
@@ -878,12 +956,14 @@ SessionImplPtr SessionImpl::create(
     const Replication::SessionDefinitionStatePtr& sessionState,
     const Replication::StateItemSeq&,
     const AsteriskSCF::SessionCommunications::V1::SessionEndpointPrx& myEndpoint,
+    const EndpointSpecificationPtr& endpointSpec,
     const RemoteServicesPtr& remoteServices,
     const Ice::ObjectAdapterPtr& adapter,
     const Logger& logger)
 {
     return new SessionServant(locator, SessionPrx::uncheckedCast(adapter->createProxy(sessionState->sessionObjectId)),
-        myEndpoint, sessionState->sessionId, sessionState->endpointItemKey, remoteServices, adapter, logger);
+        myEndpoint, sessionState->sessionId, sessionState->endpointItemKey, endpointSpec, remoteServices, adapter,
+        logger);
 }
 
 } /* End of namespace FileSessionGtw */
diff --git a/src/Session.h b/src/Session.h
index 2f432cd..72b9209 100644
--- a/src/Session.h
+++ b/src/Session.h
@@ -20,6 +20,7 @@
 #include "ReplicationAdapter.h"
 #include "ReplicatedObject.h"
 #include "RemoteServices.h"
+#include "EndpointSpecification.h"
 
 #include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
 #include <IceUtil/Shared.h>
@@ -109,6 +110,7 @@ public:
         const AsteriskSCF::SessionCommunications::V1::SessionEndpointPrx& myEndpoint,
         const std::string& id,
         const std::string& endpointId,
+        const EndpointSpecificationPtr& endpointSpecification,
         const RemoteServicesPtr& remoteServices,
         const Ice::ObjectAdapterPtr& adapter,
         const AsteriskSCF::System::Logging::Logger& logger);
@@ -125,6 +127,7 @@ public:
         const AsteriskSCF::Replication::FileSessionGateway::V1::SessionDefinitionStatePtr& sessionState,
         const AsteriskSCF::Replication::FileSessionGateway::V1::StateItemSeq& otherStateItems,
         const AsteriskSCF::SessionCommunications::V1::SessionEndpointPrx& myEndpoint,
+        const EndpointSpecificationPtr& endpointSpecification,
         const RemoteServicesPtr& remoteServices,
         const Ice::ObjectAdapterPtr& serviceAdapter,
         const AsteriskSCF::System::Logging::Logger& logger
diff --git a/test/TestSessionObject.cpp b/test/TestSessionObject.cpp
index 869d7a4..a91713c 100644
--- a/test/TestSessionObject.cpp
+++ b/test/TestSessionObject.cpp
@@ -572,7 +572,7 @@ public:
         //
         SessionServantPtr session = SessionServantPtr::dynamicCast(
             SessionImpl::create(mLocator, testProxy, testEndpoint, "TestSession", "TestEndpoint",
-                RemoteServicesPtr(), mObjectAdapter, mLogger));
+                EndpointSpecificationPtr(), RemoteServicesPtr(), mObjectAdapter, mLogger));
         BOOST_REQUIRE(session);
         return session;
     }

commit 4da7213abc36a6810c67556a37d880d394655d8f
Author: Brent Eagles <beagles at digium.com>
Date:   Thu Dec 1 15:48:03 2011 -0330

    Fix issue where configuration services was not being properly registered with
    location.

diff --git a/src/Component.cpp b/src/Component.cpp
index 5087a54..62c7cd8 100644
--- a/src/Component.cpp
+++ b/src/Component.cpp
@@ -214,6 +214,10 @@ public:
         mConfigurationFeature =
             createConfigurationFeature(mEndpointLocatorFeature->getLocator(),
                 getRemoteServices());
+        mConfigurationProxy =
+            AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx::uncheckedCast(
+                mConfigurationFeature->activate(getBackplaneAdapter()));
+        mConfigurationFeature->registerFeature(this);
     }
 
     RemoteServicesPtr getRemoteServices()
@@ -311,6 +315,7 @@ private:
     EndpointLocatorFeaturePtr mEndpointLocatorFeature;
     AsteriskSCF::Core::Routing::V1::EndpointLocatorPrx mEndpointLocatorProxy;
     ComponentFeaturePtr mConfigurationFeature;
+    AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx mConfigurationProxy;
     RemoteServicesPtr mRemoteServices;
 };
 

commit ed1903c33e3909379908a6dba957c3c761788590
Author: Brent Eagles <beagles at digium.com>
Date:   Thu Dec 1 15:36:31 2011 -0330

    - Enable configuration of router service name (not currently used) and
    file media service's service name (is currently used).
    
    - Added ONE check to Session to the rest of the external interface.
    
    - Added some code to update session info.

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1287afc..6a4eabd 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -22,6 +22,8 @@ astscf_component_add_files(FileSessionGateway
     Replicator.h
     ReplicationListener.h
     ReplicationListener.cpp
+    RemoteServices.h
+    RemoteServices.cpp
     Session.h
     Session.cpp
     )
diff --git a/src/Component.cpp b/src/Component.cpp
index e47e97b..5087a54 100644
--- a/src/Component.cpp
+++ b/src/Component.cpp
@@ -21,6 +21,7 @@
 #include "ReplicationListener.h"
 #include "ComponentDefs.h"
 #include "Configuration.h"
+#include "RemoteServices.h"
 
 #include <AsteriskSCF/Component/Component.h>
 
@@ -197,7 +198,8 @@ public:
     {
         if (!mEndpointLocatorFeature)
         {
-            mEndpointLocatorFeature = createEndpointLocatorFeature(getName(), getServiceAdapter());
+            mEndpointLocatorFeature = createEndpointLocatorFeature(getName(), getServiceAdapter(),
+                getRemoteServices());
         }
     }
 
@@ -205,10 +207,29 @@ public:
     {
         if (!mEndpointLocatorFeature)
         {
-            mEndpointLocatorFeature = createEndpointLocatorFeature(getName(), getServiceAdapter());
+            mEndpointLocatorFeature = createEndpointLocatorFeature(getName(), getServiceAdapter(),
+                getRemoteServices());
         }
 
-        mConfigurationFeature = createConfigurationFeature(mEndpointLocatorFeature->getLocator());
+        mConfigurationFeature =
+            createConfigurationFeature(mEndpointLocatorFeature->getLocator(),
+                getRemoteServices());
+    }
+
+    RemoteServicesPtr getRemoteServices()
+    {
+        if (!mRemoteServices)
+        {
+            string routingServiceName =
+                getCommunicator()->getProperties()->getPropertyWithDefault(
+                    getName() + ".RoutingServiceName", "default");
+            string mediaServiceName =
+                getCommunicator()->getProperties()->getPropertyWithDefault(
+                    getName() + ".FileMediaServiceName", "default");
+            mRemoteServices = RemoteServices::create(getServiceLocator(), routingServiceName,
+                mediaServiceName, mLogger);
+        }
+        return mRemoteServices;
     }
 
     void findRemoteServices()
@@ -256,6 +277,14 @@ public:
                 ".EndpointLocatorRegistry", "default");
             mEndpointLocatorFeature->makeReady(getServiceLocator(), routerParams);
         }
+        if (mConfigurationFeature)
+        {
+            //
+            // Configuration does not do anything like this at the moment, but we will call out
+            // just in case.
+            //
+            mConfigurationFeature->makeReady(getServiceLocator(), 0);
+        }
     }
 
     void unregisterFromRemoteServices()
@@ -264,6 +293,11 @@ public:
         {
             mEndpointLocatorFeature->suspend();
         }
+
+        if (mConfigurationFeature)
+        {
+            mConfigurationFeature->suspend();
+        }
     }
 
 private:
@@ -277,6 +311,7 @@ private:
     EndpointLocatorFeaturePtr mEndpointLocatorFeature;
     AsteriskSCF::Core::Routing::V1::EndpointLocatorPrx mEndpointLocatorProxy;
     ComponentFeaturePtr mConfigurationFeature;
+    RemoteServicesPtr mRemoteServices;
 };
 
 }; // end FileSessionGtw
diff --git a/src/Configuration.cpp b/src/Configuration.cpp
index 199fd97..a81f95f 100644
--- a/src/Configuration.cpp
+++ b/src/Configuration.cpp
@@ -88,8 +88,10 @@ class ConfigurationImpl : public AsteriskSCF::System::Configuration::V1::Configu
 {
 public:
     ConfigurationImpl(const EndpointLocatorImplPtr& endpointLocator,
+        const RemoteServicesPtr& remoteServices,
         const Logger& logger) :
         mEndpointLocator(endpointLocator),
+        mRemoteServices(remoteServices),
         mLogger(logger)
     {
     }
@@ -116,19 +118,15 @@ public:
                 }
                 continue;
             }
-
-            //
-            // TODO: get from something real.
-            //
             GeneralGroupPtr generalGroup = GeneralGroupPtr::dynamicCast(*iter);
             if (generalGroup)
             {
                 RoutingServicePtr routingService = new RoutingService;
-                routingService->serviceName = "default";
+                routingService->serviceName = mRemoteServices->getRoutingServiceName();
                 generalGroup->configurationItems[RoutingServiceItem] = routingService;
 
                 FileMediaServicePtr fileMediaService = new FileMediaService;
-                fileMediaService->serviceName = "default";
+                fileMediaService->serviceName = mRemoteServices->getMediaServiceName();
                 generalGroup->configurationItems[FileMediaServiceItem] = fileMediaService;
             }
         }
@@ -161,11 +159,11 @@ public:
             if (generalGroup)
             {
                 RoutingServicePtr routingService = new RoutingService;
-                routingService->serviceName = "default";
+                routingService->serviceName = mRemoteServices->getRoutingServiceName();
                 generalGroup->configurationItems[RoutingServiceItem] = routingService;
 
                 FileMediaServicePtr fileMediaService = new FileMediaService;
-                fileMediaService->serviceName = "default";
+                fileMediaService->serviceName = mRemoteServices->getMediaServiceName();
                 generalGroup->configurationItems[FileMediaServiceItem] = fileMediaService;
             }
         }
@@ -211,9 +209,7 @@ public:
                     RoutingServicePtr routingService = RoutingServicePtr::dynamicCast(itemIter->second);
                     if (routingService)
                     {
-                        //
-                        // TODO: we do not have a central configuration for this yet.
-                        //
+                        mRemoteServices->setRoutingServiceName(routingService->serviceName);
                     }
                     continue;
                 }
@@ -224,9 +220,7 @@ public:
                     FileMediaServicePtr fileMediaService = FileMediaServicePtr::dynamicCast(itemIter->second);
                     if (fileMediaService)
                     {
-                        //
-                        // TODO: we do not have a central configuration for this yet.
-                        //
+                        mRemoteServices->setMediaServiceName(fileMediaService->serviceName);
                     }
                     continue;
                 }
@@ -240,11 +234,31 @@ public:
     }
 
     //
-    // TODO: The configuration is not really decomposeable in this way, so I will need to look at this more
+    // TODO: Some configuration is not really decomposeable in this way, so I will need to look at this more
     // closely.
     //
-    void removeConfigurationItems(const ConfigurationGroupSeq&, const Ice::Current&)
+    void removeConfigurationItems(const ConfigurationGroupSeq& config, const Ice::Current&)
     {
+        for (ConfigurationGroupSeq::const_iterator configIter = config.begin();
+             configIter != config.end(); ++configIter)
+        {
+            GeneralGroupPtr generalGroup = GeneralGroupPtr::dynamicCast(*configIter);
+            if (generalGroup)
+            {
+                for (ConfigurationItemDict::const_iterator itemIter = generalGroup->configurationItems.begin();
+                     itemIter != generalGroup->configurationItems.end(); ++itemIter)
+                {
+                    if (itemIter->first == RoutingServiceItem)
+                    {
+                        mRemoteServices->setRoutingServiceName("default");
+                    }
+                    else if (itemIter->first == FileMediaServiceItem)
+                    {
+                        mRemoteServices->setMediaServiceName("default");
+                    }
... 1010 lines suppressed ...


-- 
asterisk-scf/integration/file_session_gateway.git



More information about the asterisk-scf-commits mailing list