[asterisk-scf-commits] asterisk-scf/integration/bridging.git branch "operation-context-propagation" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Tue Feb 14 13:29:54 CST 2012


branch "operation-context-propagation" has been updated
       via  b01f9cee61a9676c440322c84e384301977c3872 (commit)
       via  7b89c082364c2015f0576d7b4165179aadcfa22d (commit)
       via  ec893489b857a218ca5c2315e6e0d4f7e926a02e (commit)
       via  75c04280f9f1c35bf3927dc83350870ddeee2395 (commit)
       via  d613fcbc05fdaa1f05adc1bb4e62a935bd0efa37 (commit)
       via  3d96dc7671b99f124b9cf984886039ba578962c7 (commit)
       via  cc7adc199845c220745606844030d45978a7b251 (commit)
       via  31946020d908b744f0969aae1704039e6b80b24a (commit)
       via  fff860e3c1b6e62994bfcc9eefbfe0c167316874 (commit)
       via  6309c8b41438836fe368dca74a455d6ce0cc1034 (commit)
       via  dc372a69a62dc2cff4be7fccd5f34e7d4e40b1f7 (commit)
       via  aeeaed86fcbc97a9492a60242870eef57a149f0e (commit)
       via  3c93c0a3ad074ed810e4fe3f17de7fb1f9306ce7 (commit)
      from  78ac17239d10105250ba51419264713897baedee (commit)

Summary of changes:
 config/test_bridging.conf              |    4 +
 src/BridgeImpl.cpp                     |  422 ++++++++++++++++++++++----------
 src/BridgeManagerImpl.cpp              |   34 ++-
 src/BridgeManagerImpl.h                |    2 +-
 src/BridgeReplicatorService.cpp        |  210 ----------------
 src/BridgeReplicatorStateListenerI.cpp |  116 +++++++---
 src/CMakeLists.txt                     |    4 +-
 src/Component.cpp                      |   14 +-
 src/ComponentStateReplicator.cpp       |  118 +++++++++
 src/MediaSplicer.cpp                   |   10 +-
 src/ServiceUtil.h                      |   46 ----
 src/SessionCollection.cpp              |   22 ++
 src/SessionCollection.h                |    2 +
 src/SessionListener.cpp                |    6 +
 src/SessionWrapper.cpp                 |   29 ++-
 src/SessionWrapper.h                   |    4 +-
 src/Tasks.h                            |    5 +
 test/CMakeLists.txt                    |    5 +-
 test/TestBridging.cpp                  |  116 ++++++---
 19 files changed, 689 insertions(+), 480 deletions(-)
 delete mode 100644 src/BridgeReplicatorService.cpp
 create mode 100644 src/ComponentStateReplicator.cpp


- Log -----------------------------------------------------------------
commit b01f9cee61a9676c440322c84e384301977c3872
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Feb 14 15:59:43 2012 -0330

    Fix missing library lines.

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 4c6988c..eae777d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -23,7 +23,7 @@ astscf_component_add_ice_libraries(BridgeComponentTest IceBox)
 astscf_component_add_boost_libraries(BridgeComponentTest unit_test_framework thread)
 astscf_component_add_slice_collection_libraries(BridgeComponentTest ASTSCF TEST_CHANNEL)
 astscf_component_build_icebox(BridgeComponentTest)
-target_link_libraries(BridgeComponentTest LoggingClient)
+target_link_libraries(BridgeComponentTest LoggingClient ASTSCFIceUtilCpp)
 astscf_test_icebox(BridgeComponentTest config/test_bridging.conf)
 
 astscf_component_init(BridgeUnitTests)
@@ -40,5 +40,5 @@ astscf_component_add_ice_libraries(BridgeUnitTests Ice)
 astscf_component_add_boost_libraries(BridgeUnitTests unit_test_framework thread)
 astscf_component_add_slice_collection_libraries(BridgeUnitTests ASTSCF)
 astscf_component_build_standalone(BridgeUnitTests)
-target_link_libraries(BridgeUnitTests LoggingClient)
+target_link_libraries(BridgeUnitTests LoggingClient ASTSCFIceUtilCpp)
 astscf_test_boost(BridgeUnitTests)

commit 7b89c082364c2015f0576d7b4165179aadcfa22d
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Feb 14 12:21:01 2012 -0330

    Sprinkle operation context cache usage.. so duplicate calls are prevented, but
    idempotent semantics aren't quite there yet.

diff --git a/src/BridgeImpl.cpp b/src/BridgeImpl.cpp
index 509ba79..b885f84 100755
--- a/src/BridgeImpl.cpp
+++ b/src/BridgeImpl.cpp
@@ -30,6 +30,8 @@
 #include "SessionWrapper.h"
 #include "SessionOperations.h"
 #include "SessionListener.h"
+#include <AsteriskSCF/Helpers/OperationContextCache.h>
+#include <AsteriskSCF/Helpers/OperationContext.h>
 
 using namespace AsteriskSCF::System::Logging;
 using namespace AsteriskSCF::SessionCommunications::V1;
@@ -330,8 +332,7 @@ private:
     //
     Logger mLogger;
 
-    typedef map<string, GenericAMDCallbackIfPtr> OperationTracker;
-    OperationTracker mOperationsInProgress;
+    AsteriskSCF::Helpers::OperationContextCachePtr mOperationContextCache;
 
     void statePreCheck();
     BridgeStateItemPtr createUpdate();
@@ -471,7 +472,7 @@ protected:
         if (sessionController)
         {
             // Forward the info via the SessionController for this session.
-            sessionController->updateRedirections(currentRedirections);
+            sessionController->updateRedirections(AsteriskSCF::createContext(), currentRedirections);
         }
     }
 
@@ -596,7 +597,7 @@ protected:
         if (sessionController)
         {
             // Forward the info via the SessionController for this session.
-            sessionController->updateConnectedLine(currentConnectedLine);
+            sessionController->updateConnectedLine(AsteriskSCF::createContext(), currentConnectedLine);
         }
     }
 
@@ -703,7 +704,7 @@ protected:
         SessionControllerPrx sessionController =  destinationSession->getSessionController();
         if (sessionController)
         {
-            sessionController->updateCallerID(currentCallerID);
+            sessionController->updateCallerID(AsteriskSCF::createContext(), currentCallerID);
         }
     }
 
@@ -750,6 +751,7 @@ protected:
         if (!wrapper)
         {
             mLogger(Debug) << "Unable to find matching session for, returning early with true.";
+            return true;
         }
 
         PartyIdHooksPtr partyIdHooks = mBridge->getPartyIdHooks();
@@ -777,7 +779,9 @@ protected:
             }
         }
 
+        //
         // Cache this value.
+        //
         wrapper->setConnectedLine(currentConnectedLine);
 
         return true;
@@ -918,9 +922,15 @@ private:
 class BridgeSessionController : public SessionController
 {
 public:
-    BridgeSessionController(const BridgeImplPtr& bridge,
-                            const SessionWrapperPtr& self,
-                            const Logger& logger) : mBridge(bridge), mSelf(self), mLogger(logger) { }
+    BridgeSessionController(const BridgeImplPtr& bridge, const SessionWrapperPtr& self,
+                            const Logger& logger) : 
+        mBridge(bridge), 
+        mSelf(self), 
+        mLogger(logger),
+        mOperationCache(new AsteriskSCF::Helpers::OperationContextCache(
+                AsteriskSCF::Helpers::OperationCacheDefaultTTL))
+    { 
+    }
 
     void changeStreamStates_async(
         const AsteriskSCF::SessionCommunications::V1::AMD_SessionController_changeStreamStatesPtr& cb,
@@ -932,25 +942,48 @@ public:
     }
 
     void addStreams_async(const AsteriskSCF::SessionCommunications::V1::AMD_SessionController_addStreamsPtr& cb,
-        const AsteriskSCF::System::V1::OperationContextPtr&,
+        const AsteriskSCF::System::V1::OperationContextPtr& context,
         const AsteriskSCF::Media::V1::StreamInformationDict& streams, const Ice::Current&)
     {
+        if (!mOperationCache->addOperationContext(context))
+        {
+            //
+            // XXXX there needs to be away to give a good response here!!!
+            //
+            cb->ice_response(AsteriskSCF::Media::V1::StreamInformationDict());
+            return;
+        }
         AddStreamsOperationPtr op = new AddStreamsOperation(cb, mSelf, streams, mLogger);
         mBridge->getSessions()->visitSessions(*op);
     }
 
     void removeStreams_async(const AsteriskSCF::SessionCommunications::V1::AMD_SessionController_removeStreamsPtr& cb,
-        const AsteriskSCF::System::V1::OperationContextPtr&,
+        const AsteriskSCF::System::V1::OperationContextPtr& context,
         const AsteriskSCF::Media::V1::StreamInformationDict& streams, const Ice::Current&)
     {
+        if (!mOperationCache->addOperationContext(context))
+        {
+            //
+            // Silently swallow and ignore the duplicate request.
+            //
+            cb->ice_response();
+            return;
+        }
         RemoveStreamsOperation op(mSelf, streams);
         mBridge->getSessions()->visitSessions(op);
         cb->ice_response();
     }
 
-    void updateConnectedLine(const AsteriskSCF::System::V1::OperationContextPtr&,
+    void updateConnectedLine(const AsteriskSCF::System::V1::OperationContextPtr& context,
         const ConnectedLinePtr& connectedLine, const Ice::Current&)
     {
+        if (!mOperationCache->addOperationContext(context))
+        {
+            //
+            // Silently swallow and ignore the duplicate request.
+            //
+            return;
+        }
         mBridge->updateConnectedLine(mSelf, connectedLine);
     }
 
@@ -963,9 +996,16 @@ public:
         return;
     }
 
-    void updateRedirections(const AsteriskSCF::System::V1::OperationContextPtr&,
+    void updateRedirections(const AsteriskSCF::System::V1::OperationContextPtr& context,
         const RedirectionsPtr& redirections, const ::Ice::Current&) 
     {
+        if (!mOperationCache->addOperationContext(context))
+        {
+            //
+            // Silently swallow and ignore the duplicate request.
+            //
+            return;
+        }
         mBridge->updateRedirections(mSelf, redirections);
     }
 
@@ -973,6 +1013,7 @@ private:
     BridgeImplPtr mBridge;
     SessionWrapperPtr mSelf;
     Logger mLogger;
+    AsteriskSCF::Helpers::OperationContextCachePtr mOperationCache;
 };
 
 class SetAndGetSessionControllerTask : public QueuedTask
@@ -1437,7 +1478,8 @@ BridgeImpl::BridgeImpl(const string& name, const Ice::ObjectAdapterPtr& adapter,
     mListeners(listenerMgr),
     mReplicator(replicator),
     mSessionListener(createSessionListener(mSessions, logger)),
-    mLogger(logger)
+    mLogger(logger),
+    mOperationContextCache(new AsteriskSCF::Helpers::OperationContextCache(AsteriskSCF::Helpers::OperationCacheDefaultTTL))
 {
     mLogger(Trace) << FUNLOG << ": creating a new Bridge with " << listeners.size() << " default listeners";
     for (vector<BridgeListenerPrx>::const_iterator i = listeners.begin(); 
@@ -1516,6 +1558,12 @@ void BridgeImpl::addSessions_async(const AMD_Bridge_addSessionsPtr& callback,
 {
     try
     {
+        if (!mOperationContextCache->addOperationContext(operationContext))
+        {
+            callback->ice_response();
+            return;
+        }
+
         mSessions->reap();
         SessionSeq sessions;
         sessions.resize(sessionInfos.size());
@@ -1532,35 +1580,6 @@ void BridgeImpl::addSessions_async(const AMD_Bridge_addSessionsPtr& callback,
         statePreCheck();
         mLogger(Trace) << FUNLOG << ": adding " << sessions.size() << " sessions";
         SessionsTrackerPtr tracker(new SessionsTracker);
-        if (operationContext)
-        {
-            OperationTracker::const_iterator iter = mOperationsInProgress.find(operationContext->id);
-            if (iter != mOperationsInProgress.end())
-            {
-                Ice::AMDCallbackPtr oldCB = iter->second->setCallback(callback);
-                if (oldCB)
-                {
-                    AMD_Bridge_addSessionsPtr superSededCallback = AMD_Bridge_addSessionsPtr::dynamicCast(oldCB);
-                    if (!superSededCallback)
-                    {
-                        assert("There is a type mismatch on operation context! This is definitely a bug." == 0);
-                        mLogger(Error) << "Type mismatch on operations in progress and recorded AMD callback.";
-            
-                    }
-                    oldCB->ice_exception(AsteriskSCF::System::V1::OperationCallCancelledException(
-                            "Operation overridden by subsequent invocation.", 
-                            AsteriskSCF::System::V1::Superseded));
-                    return;
-                }
-                else
-                {
-                    callback->ice_exception(AsteriskSCF::System::V1::OperationCallCancelledException(
-                            "Operation already in progress.",
-                            AsteriskSCF::System::V1::Duplicate));
-                }
-            }
-        }
-
         
         QueuedTasks tasks;
         tasks.push_back(new UnplugMedia(this));
@@ -1610,11 +1629,19 @@ void BridgeImpl::addSessions_async(const AMD_Bridge_addSessionsPtr& callback,
 }
 
 void BridgeImpl::removeSessions_async(const AMD_Bridge_removeSessionsPtr& callback,
-    const AsteriskSCF::System::V1::OperationContextPtr&, const SessionSeq& sessions,
-        const Ice::Current&)
+    const AsteriskSCF::System::V1::OperationContextPtr& operationContext, const SessionSeq& sessions,
+    const Ice::Current&)
 {
     try
     {
+        if (!mOperationContextCache->addOperationContext(operationContext))
+        {
+            //
+            // Ignore duplicate.
+            //
+            callback->ice_response();
+            return;
+        }
         if (sessions.empty())
         {
             callback->ice_response();
@@ -1798,8 +1825,13 @@ void BridgeImpl::destroy(const Ice::Current& current)
     }
 }
 
-void BridgeImpl::addListener(const AsteriskSCF::System::V1::OperationContextPtr&, const BridgeListenerPrx& listener, const Ice::Current& current)
+void BridgeImpl::addListener(const AsteriskSCF::System::V1::OperationContextPtr& operationContext, 
+    const BridgeListenerPrx& listener, const Ice::Current& current)
 {
+    if (!mOperationContextCache->addOperationContext(operationContext))
+    {
+        return;
+    }
     mLogger(Trace) << FUNLOG << ":" <<  objectIdFromCurrent(current) << " with bridge listener: " <<
         (listener ? "(nil)" : mObjAdapter->getCommunicator()->identityToString(listener->ice_getIdentity()));
     if (!listener)
@@ -1821,9 +1853,13 @@ void BridgeImpl::addListener(const AsteriskSCF::System::V1::OperationContextPtr&
     }
 }
 
-void BridgeImpl::removeListener(const AsteriskSCF::System::V1::OperationContextPtr&,
+void BridgeImpl::removeListener(const AsteriskSCF::System::V1::OperationContextPtr& operationContext,
     const BridgeListenerPrx& listener, const Ice::Current& current)
 {
+    if (!mOperationContextCache->addOperationContext(operationContext))
+    {
+        return;
+    }
     mLogger(Trace) << FUNLOG << ":" <<  objectIdFromCurrent(current) << " with bridge listener: " <<
         (listener ? "(nil)" : mObjAdapter->getCommunicator()->identityToString(listener->ice_getIdentity()));
     if (!listener)
@@ -1854,13 +1890,18 @@ void BridgeImpl::removeListener(const AsteriskSCF::System::V1::OperationContextP
 }
 
 void BridgeImpl::replaceSession_async(const AMD_Bridge_replaceSessionPtr& callback,
-    const AsteriskSCF::System::V1::OperationContextPtr&,
+    const AsteriskSCF::System::V1::OperationContextPtr& operationContext,
     const SessionPrx& sessionToReplace,
     const SessionWithSessionInfoSeq& newSessionInfos,
     const Ice::Current& current)
 {
     try
     {
+        if (!mOperationContextCache->addOperationContext(operationContext))
+        {
+            callback->ice_response();
+            return;
+        }
         mLogger(Trace) << FUNLOG << ":" << objectIdFromCurrent(current);
         mSessions->reap();
         SessionSeq newSessions;
@@ -1868,7 +1909,7 @@ void BridgeImpl::replaceSession_async(const AMD_Bridge_replaceSessionPtr& callba
         std::transform(newSessionInfos.begin(), newSessionInfos.end(), newSessions.begin(), extractSession);
         checkSessions(newSessions);
         statePreCheck();
-        
+
         SessionWrapperPtr session = mSessions->getSession(sessionToReplace);
         //
         // If the session did not exist on this bridge, then this operation should not proceed.
@@ -1890,7 +1931,7 @@ void BridgeImpl::replaceSession_async(const AMD_Bridge_replaceSessionPtr& callba
         // list of known sessions now so it doesn't get in the way.
         //
         mSessions->removeSession(session->getBridgedSession());
-        
+
         SessionsTrackerPtr tracker(new SessionsTracker);
         QueuedTasks tasks;
         BridgeCookies cookies;
@@ -1946,8 +1987,13 @@ void BridgeImpl::replaceSession_async(const AMD_Bridge_replaceSessionPtr& callba
     }
 }
 
-void BridgeImpl::setCookies(const AsteriskSCF::System::V1::OperationContextPtr&, const BridgeCookies& cookies, const Ice::Current& current)
+void BridgeImpl::setCookies(const AsteriskSCF::System::V1::OperationContextPtr& operationContext, 
+    const BridgeCookies& cookies, const Ice::Current& current)
 {
+    if (!mOperationContextCache->addOperationContext(operationContext))
+    {
+        return;
+    }
     mLogger(Trace) << FUNLOG << ":" << objectIdFromCurrent(current);
     BridgeStateItemPtr update;
     {
@@ -1961,9 +2007,13 @@ void BridgeImpl::setCookies(const AsteriskSCF::System::V1::OperationContextPtr&,
     pushUpdate(update);
 }
 
-void BridgeImpl::removeCookies(const AsteriskSCF::System::V1::OperationContextPtr&,
+void BridgeImpl::removeCookies(const AsteriskSCF::System::V1::OperationContextPtr& operationContext,
     const BridgeCookies& cookies, const Ice::Current& current)
 {
+    if (!mOperationContextCache->addOperationContext(operationContext))
+    {
+        return;
+    }
     mLogger(Trace) << FUNLOG << ":" << objectIdFromCurrent(current);
     BridgeStateItemPtr update;
     {
diff --git a/src/BridgeManagerImpl.cpp b/src/BridgeManagerImpl.cpp
index 552dd84..5eae3de 100644
--- a/src/BridgeManagerImpl.cpp
+++ b/src/BridgeManagerImpl.cpp
@@ -28,6 +28,7 @@
 #include <AsteriskSCF/System/ExceptionsIf.h>
 #include <AsteriskSCF/System/Component/ComponentServiceIf.h>
 #include <AsteriskSCF/Helpers/OperationContext.h>
+#include <AsteriskSCF/Helpers/OperationContextCache.h>
 
 using namespace AsteriskSCF::System::Logging;
 using namespace AsteriskSCF::System;
@@ -151,6 +152,7 @@ private:
     ServiceManagementPrx mCreationExtensionPointServicePrx;
 
     BridgeManagerStateItemPtr mState;
+    AsteriskSCF::Helpers::OperationContextCachePtr mOperationCache;
 
     void reap();
     void statePreCheck(const string&);
@@ -170,7 +172,8 @@ BridgeManagerImpl::BridgeManagerImpl(const Ice::ObjectAdapterPtr& adapter,
         mAdapter(adapter),
         mReplicationContext(replicationContext), 
         mLogger(logger),
-        mState(new BridgeManagerStateItem)
+        mState(new BridgeManagerStateItem),
+        mOperationCache(new AsteriskSCF::Helpers::OperationContextCache(AsteriskSCF::Helpers::OperationCacheDefaultTTL))
 {
     mLogger(Info) << "Created AsteriskSCF Session-Oriented Bridge Manager." ;
     mListeners = new BridgeManagerListenerMgr(mAdapter->getCommunicator(), mName, mSourceProxy);
@@ -226,7 +229,7 @@ private:
 };
 
 void BridgeManagerImpl::createBridge_async(const AMD_BridgeManager_createBridgePtr& callback,
-    const AsteriskSCF::System::V1::OperationContextPtr&,
+    const AsteriskSCF::System::V1::OperationContextPtr& context,
     const SessionPrx& source, const SessionSeq& sessions,
     const BridgeListenerPrx& listener, const CallerPtr& callerID, const RedirectionsPtr& redirects,
     const Ice::Current& current)
@@ -238,6 +241,13 @@ void BridgeManagerImpl::createBridge_async(const AMD_BridgeManager_createBridgeP
         statePreCheck(BOOST_CURRENT_FUNCTION);
         reap();
 
+        if (!mOperationCache->addOperationContext(context))
+        {
+            callback->ice_exception(
+                AsteriskSCF::System::V1::OperationCallCancelledException(context->id,
+                    AsteriskSCF::System::V1::Duplicate));
+        }
+
         string stringId = string("bridge.") + IceUtil::generateUUID();
         Ice::Identity id(mAdapter->getCommunicator()->stringToIdentity(stringId));
         BridgePrx prx(BridgePrx::uncheckedCast(mAdapter->createProxy(id)));
diff --git a/src/ComponentStateReplicator.cpp b/src/ComponentStateReplicator.cpp
index d7505dc..a3d8ba9 100644
--- a/src/ComponentStateReplicator.cpp
+++ b/src/ComponentStateReplicator.cpp
@@ -52,8 +52,7 @@ public:
       AsteriskSCF::Component::ComponentStateReplicator(
            lg, 
            AsteriskSCF::Replication::BridgeService::V1::StateReplicatorComponentCategory, 
-           false,
-           "")
+           false)
     {
     }
 

commit ec893489b857a218ca5c2315e6e0d4f7e926a02e
Merge: 6309c8b 75c0428
Author: Brent Eagles <beagles at digium.com>
Date:   Mon Feb 13 15:35:33 2012 -0330

    Merge 'release/bridging/master' into operation-context-propagation.

diff --cc src/BridgeImpl.cpp
index bd7673d,688e61f..509ba79
--- a/src/BridgeImpl.cpp
+++ b/src/BridgeImpl.cpp
@@@ -1689,9 -1690,22 +1783,22 @@@ void BridgeImpl::destroy(const Ice::Cur
      // Remove references to the session listener implementation.
      //
      mObjAdapter->remove(mSessionListenerPrx->ice_getIdentity());
+ 
+     try
+     {
+         if (replicate())
+         {
+             Ice::StringSeq keys;
+             keys.push_back(mState->key);
+             mReplicator->removeState(keys);
+         }
+     }
+     catch (const Ice::Exception&)
+     {
+     }
  }
  
 -void BridgeImpl::addListener(const BridgeListenerPrx& listener, const Ice::Current& current)
 +void BridgeImpl::addListener(const AsteriskSCF::System::V1::OperationContextPtr&, const BridgeListenerPrx& listener, const Ice::Current& current)
  {
      mLogger(Trace) << FUNLOG << ":" <<  objectIdFromCurrent(current) << " with bridge listener: " <<
          (listener ? "(nil)" : mObjAdapter->getCommunicator()->identityToString(listener->ice_getIdentity()));

commit 75c04280f9f1c35bf3927dc83350870ddeee2395
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Fri Feb 10 11:38:42 2012 -0600

    Changes to base ComponentStateReplicator constructor args.

diff --git a/src/ComponentStateReplicator.cpp b/src/ComponentStateReplicator.cpp
index ce0410f..d7505dc 100644
--- a/src/ComponentStateReplicator.cpp
+++ b/src/ComponentStateReplicator.cpp
@@ -49,7 +49,11 @@ class ComponentStateReplicator : public AsteriskSCF::Component::ComponentStateRe
 {
 public:
     ComponentStateReplicator() :
-      AsteriskSCF::Component::ComponentStateReplicator(lg, AsteriskSCF::Replication::BridgeService::V1::StateReplicatorComponentCategory, false)
+      AsteriskSCF::Component::ComponentStateReplicator(
+           lg, 
+           AsteriskSCF::Replication::BridgeService::V1::StateReplicatorComponentCategory, 
+           false,
+           "")
     {
     }
 

commit d613fcbc05fdaa1f05adc1bb4e62a935bd0efa37
Author: Brent Eagles <beagles at digium.com>
Date:   Thu Feb 9 00:13:25 2012 -0330

    - More explicit cleanup of session collections.
    - Extra cleanup added to test suite.
    - Fix an insane bug in SessionCollection
    - Figured out that command line arguments must be used to disable
      the global leak detection, or the detect_memory_leaks(0) call has
      to be placed so it executes *after* boost::test::init() is called.
    - Knock the logging level down a bit in the configuration.

diff --git a/config/test_bridging.conf b/config/test_bridging.conf
index 18f8235..2854d81 100644
--- a/config/test_bridging.conf
+++ b/config/test_bridging.conf
@@ -82,7 +82,7 @@ TestBridge.ServiceAdapter.ThreadPool.Size=2
 TestBridge.BackplaneAdapter.Endpoints=default -h 127.0.0.1 -p 57001
 TestBridge.BackplaneAdapter.ThreadPool.Size=2
 TestBridge.Standby=false
-TestBridge.LogLevel=0
+TestBridge.LogLevel=1
 
 TestBridge2.InstanceName=TestBridge2
 TestBridge2.BridgeManagerObjectId=TestBridgeManager2
@@ -91,7 +91,7 @@ TestBridge2.ServiceAdapter.Endpoints=default -h 127.0.0.1 -p 57010
 TestBridge2.ServiceAdapter.ThreadPool.Size=4
 TestBridge2.BackplaneAdapter.Endpoints=default -h 127.0.0.1 -p 57011
 TestBridge2.BackplaneAdapter.ThreadPool.Size=4
-TestBridge2.LogLevel=0
+TestBridge2.LogLevel=1
 #Ice.Trace.Network=1
 #Ice.Trace.Protocol=1
 
diff --git a/src/BridgeImpl.cpp b/src/BridgeImpl.cpp
index 765ae55..688e61f 100755
--- a/src/BridgeImpl.cpp
+++ b/src/BridgeImpl.cpp
@@ -1613,6 +1613,7 @@ void BridgeImpl::shutdown(const Ice::Current& current)
         update = createUpdate();
     }
     pushUpdate(update);
+    SessionCollectionPtr currentCollection;
     {
         //
         // Currently the slice defines the response "Normal Clearing" as the default
@@ -1630,6 +1631,12 @@ void BridgeImpl::shutdown(const Ice::Current& current)
         //
         mObjAdapter->remove(mSessionListenerPrx->ice_getIdentity());
         mSessionListener = 0;
+        currentCollection = mSessions;
+        mSessions = 0;
+    }
+    if (currentCollection)
+    {
+        currentCollection->destroy();
     }
     
     try
@@ -1652,6 +1659,7 @@ void BridgeImpl::destroy(const Ice::Current& current)
 {
     mLogger(Trace) << FUNLOG << ":" <<  objectIdFromCurrent(current);
     BridgeStateItemPtr update;
+    SessionCollectionPtr currentCollection;
     {
         boost::unique_lock<boost::shared_mutex> lock(mLock);
         if (mState->runningState == ShuttingDown)
@@ -1669,6 +1677,12 @@ void BridgeImpl::destroy(const Ice::Current& current)
         mListeners->stopped(getCookies());
         mSessionListener = 0;
         update = createUpdate();
+        currentCollection = mSessions;
+        mSessions = 0;
+    }
+    if (currentCollection)
+    {
+        currentCollection->destroy();
     }
     pushUpdate(update);
 
@@ -1916,12 +1930,14 @@ bool BridgeImpl::destroyed()
 
 void BridgeImpl::destroyImpl()
 {
+    SessionCollectionPtr currentCollection;
     try
     {
         boost::unique_lock<boost::shared_mutex> lock(mLock);
         mState->runningState = Destroyed;
+        currentCollection = mSessions;
         mSessions = 0;
-
+        mSessionListener = 0;
         if (mObjAdapter && mState)
         {
             mObjAdapter->remove(mObjAdapter->getCommunicator()->stringToIdentity(mState->bridgeId));
@@ -1931,6 +1947,11 @@ void BridgeImpl::destroyImpl()
     {
     }
 
+    if (currentCollection)
+    {
+        currentCollection->destroy();
+    }
+
     try
     {
         if (replicate())
diff --git a/src/SessionCollection.cpp b/src/SessionCollection.cpp
index 9b6c815..2f09558 100644
--- a/src/SessionCollection.cpp
+++ b/src/SessionCollection.cpp
@@ -232,7 +232,7 @@ void SessionCollection::destroy()
         copy = mMap;
         mMap.clear();
     }
-    for (SessionMap::iterator i = copy.begin(); i != copy.end();)
+    for (SessionMap::iterator i = copy.begin(); i != copy.end(); ++i)
     {
         i->second->destroy();
     }
diff --git a/src/SessionWrapper.cpp b/src/SessionWrapper.cpp
index 5996a76..6854188 100644
--- a/src/SessionWrapper.cpp
+++ b/src/SessionWrapper.cpp
@@ -397,6 +397,17 @@ SessionWrapper::SessionWrapper(const BridgedSessionPtr& session,
 {
 }
 
+SessionWrapper::~SessionWrapper()
+{
+    try
+    {
+        mLogger(Trace) << "SessionWrapper::~SessionWrapper(): " << mId;
+    }
+    catch (...)
+    {
+    }
+}
+
 bool SessionWrapper::isConnected()
 {
     boost::shared_lock<boost::shared_mutex> lock(mLock);
diff --git a/src/SessionWrapper.h b/src/SessionWrapper.h
index b03acc4..1dcc56e 100644
--- a/src/SessionWrapper.h
+++ b/src/SessionWrapper.h
@@ -35,6 +35,8 @@ public:
             const AsteriskSCF::BridgeService::ReplicatorSmartPrx& replicator,
             const AsteriskSCF::System::Logging::Logger& logger);
 
+    virtual ~SessionWrapper();
+
     /**
      * The following methods are helper methods for handling changes to sessions
      * based on internal operations or listener calls.
diff --git a/src/Tasks.h b/src/Tasks.h
index 3487abb..882cab1 100644
--- a/src/Tasks.h
+++ b/src/Tasks.h
@@ -321,6 +321,8 @@ public:
             current->fail();
             current = popNextTask();
         }
+        boost::unique_lock<boost::shared_mutex> lock(mLock);
+        mTasks.clear();
     }
 
     //
@@ -345,6 +347,8 @@ public:
             current->destroy();
             current = popNextTask();
         }
+        boost::unique_lock<boost::shared_mutex> lock(mLock);
+        mTasks.clear();
     }
 
     /**
@@ -407,6 +411,7 @@ protected:
     AsteriskSCF::System::Logging::Logger mLogger;
     bool mStopped;
     std::string mName;
+
 };
 typedef IceUtil::Handle<Executor> ExecutorPtr;
 
diff --git a/test/TestBridging.cpp b/test/TestBridging.cpp
index 1dc64e2..d096398 100644
--- a/test/TestBridging.cpp
+++ b/test/TestBridging.cpp
@@ -207,6 +207,7 @@ public:
         // of char*.
         //
         mArgs.insert(mArgs.begin(), "BRIDGE_TEST_SERVICE");
+        mArgs.push_back("--detect_memory_leaks=0");
         for (Ice::StringSeq::const_iterator i = mArgs.begin(); i != mArgs.end(); ++i)
         {
             mArgv.push_back(i->c_str());
@@ -1559,9 +1560,23 @@ public:
         int argc = (int) globalTestEnvironment->argc();
         char** argv = globalTestEnvironment->argv();
 
-        ::boost::debug::detect_memory_leaks(false);
         ::boost::unit_test::unit_test_log.set_stream( std::cout );
         int r = ::boost::unit_test::unit_test_main(&init_unit_test, argc, argv);
+        try
+        {
+            IceEnvironment testEnv(globalTestEnvironment->properties());
+            BridgeManagerPrx mgrPrx = globalTestEnvironment->primaryBridgeManager();
+            cleanupBridges(mgrPrx);
+            mgrPrx->shutdown();
+        }
+        catch (const std::exception& ex)
+        {
+            std::cerr << "Unexpected Ice exception " << ex.what() << std::endl;
+        }
+        catch (...)
+        {
+            std::cerr << "Unexpected exception" << std::endl;
+        }
         exit(r);
 
         Ice::InitializationData initData;
@@ -1570,8 +1585,15 @@ public:
         IceBox::ServiceManagerPrx mgr = IceBox::ServiceManagerPrx::checkedCast(t->propertyToProxy("IceBoxMgr.Proxy"));
         if (mgr)
         {
-            mgr->shutdown();
+            try
+            {
+                mgr->shutdown();
+            }
+            catch (...)
+            {
+            }
         }
+        globalTestEnvironment = 0;
     }
 };
 
@@ -1587,6 +1609,7 @@ public:
     void start(const std::string&, const Ice::CommunicatorPtr& communicator, const Ice::StringSeq& args)
     {
         globalTestEnvironment = new TestEnvironment(communicator, args);
+
         mRunner = new TestRunner;
         mRunner->start();
     }

commit 3d96dc7671b99f124b9cf984886039ba578962c7
Author: Brent Eagles <beagles at digium.com>
Date:   Wed Feb 8 20:57:43 2012 -0330

    Disable memory leak dump and specify std::cout output (a-la routing component test)

diff --git a/test/TestBridging.cpp b/test/TestBridging.cpp
index 69410c3..1dc64e2 100644
--- a/test/TestBridging.cpp
+++ b/test/TestBridging.cpp
@@ -1558,6 +1558,9 @@ public:
     {
         int argc = (int) globalTestEnvironment->argc();
         char** argv = globalTestEnvironment->argv();
+
+        ::boost::debug::detect_memory_leaks(false);
+        ::boost::unit_test::unit_test_log.set_stream( std::cout );
         int r = ::boost::unit_test::unit_test_main(&init_unit_test, argc, argv);
         exit(r);
 

commit cc7adc199845c220745606844030d45978a7b251
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Feb 7 16:53:15 2012 -0330

    Set a local test timeout override because this test takes a smidge too long!

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 34ceed8..d883e73 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -2,6 +2,7 @@ include_directories(${logger_dir}/include)
 include_directories(${astscf-ice-util-cpp_dir}/include)
 
 include_directories(../src)
+set(LOCAL_TIMEOUT_OVERRIDE 120)
 
 astscf_slice_include_collection(TEST_CHANNEL)
 

commit 31946020d908b744f0969aae1704039e6b80b24a
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Feb 7 16:27:38 2012 -0330

        - Fix up some logging messages.
    
        - Null handle checks in some of the tasks (exceptions were showing up in
          the test suite.
    
        - Quick hack for setting log level by confiugration.. the component's
          logger isn't being used, instead the file scoped copy is.. .wrong! Still,
          didn't change that.. enough unrelated changes made in this commit already.
    
        - A lot of stuff was not calling removeState when it was going away.
    
        - The test suite doesn't really do replication correctly.. which might be
          part of the problem.

diff --git a/config/test_bridging.conf b/config/test_bridging.conf
index 3b9e504..18f8235 100644
--- a/config/test_bridging.conf
+++ b/config/test_bridging.conf
@@ -82,6 +82,7 @@ TestBridge.ServiceAdapter.ThreadPool.Size=2
 TestBridge.BackplaneAdapter.Endpoints=default -h 127.0.0.1 -p 57001
 TestBridge.BackplaneAdapter.ThreadPool.Size=2
 TestBridge.Standby=false
+TestBridge.LogLevel=0
 
 TestBridge2.InstanceName=TestBridge2
 TestBridge2.BridgeManagerObjectId=TestBridgeManager2
@@ -90,6 +91,9 @@ TestBridge2.ServiceAdapter.Endpoints=default -h 127.0.0.1 -p 57010
 TestBridge2.ServiceAdapter.ThreadPool.Size=4
 TestBridge2.BackplaneAdapter.Endpoints=default -h 127.0.0.1 -p 57011
 TestBridge2.BackplaneAdapter.ThreadPool.Size=4
+TestBridge2.LogLevel=0
+#Ice.Trace.Network=1
+#Ice.Trace.Protocol=1
 
 #
 # Configuration for the bridge state replicator.
diff --git a/src/BridgeImpl.cpp b/src/BridgeImpl.cpp
index 1a88527..765ae55 100755
--- a/src/BridgeImpl.cpp
+++ b/src/BridgeImpl.cpp
@@ -304,22 +304,34 @@ public:
 protected:
     bool executeImpl()
     {
+        mLogger(Trace) << FUNLOG;
+        if (!mSourceSession)
+        {
+            mLogger(Trace) << FUNLOG <<  " Source session is nil, returning early with true";
+            return true;
+        }
         try
         {
-            mLogger(Trace) << FUNLOG;
 
             // Forward the ConnectedLine to each bridged session.
             SessionSeq sessions = mBridge->getSessions()->getSessionSeq();
             for(SessionSeq::iterator i = sessions.begin();
                 i != sessions.end(); ++i)
             {
-                if ((*i)->ice_getIdentity() == mSourceSession->ice_getIdentity())
+                if (!(*i) || (*i)->ice_getIdentity() == mSourceSession->ice_getIdentity())
                 {
                     continue;
                 }
 
                 SessionWrapperPtr destSessionWrapper = mBridge->getSessions()->getSession(*i);
-                forward(destSessionWrapper, mRedirections);
+                if (destSessionWrapper)
+                {
+                    forward(destSessionWrapper, mRedirections);
+                }
+                else
+                {
+                    mLogger(Debug) << " Destination wrapper for session does not exist, continuing";
+                }
             }
 
         }
@@ -339,31 +351,37 @@ protected:
         RedirectionsPtr destSpecificRedirections = redirections;
 
         PartyIdHooksPtr partyIdHooks = mBridge->getPartyIdHooks();
-
-        // Allow the ForwardingRedirectionsPartyId hooks to alter the Redirections record. 
-        for(vector<ForwardingRedirectionsPartyIdHookPrx>::const_iterator i = partyIdHooks->forwardingRedirectionsHooks.begin();
-            i != partyIdHooks->forwardingRedirectionsHooks.end(); ++i)
+        if (partyIdHooks)
         {
-            try
+            // Allow the ForwardingRedirectionsPartyId hooks to alter the Redirections record. 
+            for(vector<ForwardingRedirectionsPartyIdHookPrx>::const_iterator i = partyIdHooks->forwardingRedirectionsHooks.begin();
+                i != partyIdHooks->forwardingRedirectionsHooks.end(); ++i)
             {
-                // Apply this hook. 
-                AsteriskSCF::System::Hook::V1::HookResult hookResult = (*i)->modifyForwardingRedirections(mSourceSession,
-                    destinationSession->getSession(),
-                    currentRedirections, destSpecificRedirections);
-
-                if (hookResult.status == AsteriskSCF::System::Hook::V1::Succeeded)
+                try
                 {
-                    currentRedirections = destSpecificRedirections;
+                    // Apply this hook. 
+                    AsteriskSCF::System::Hook::V1::HookResult hookResult = (*i)->modifyForwardingRedirections(mSourceSession,
+                        destinationSession->getSession(),
+                        currentRedirections, destSpecificRedirections);
+
+                    if (hookResult.status == AsteriskSCF::System::Hook::V1::Succeeded)
+                    {
+                        currentRedirections = destSpecificRedirections;
+                    }
+                }
+                catch(const std::exception& e)
+                {
+                    mLogger(Warning) << FUNLOG << " : " << e.what();
                 }
-            }
-            catch(const std::exception& e)
-            {
-                mLogger(Warning) << FUNLOG << " : " << e.what();
             }
         }
 
-        // Forward the info via the SessionController for this session.
-        destinationSession->getSessionController()->updateRedirections(currentRedirections);
+        SessionControllerPrx sessionController = destinationSession->getSessionController();
+        if (sessionController)
+        {
+            // Forward the info via the SessionController for this session.
+            sessionController->updateRedirections(currentRedirections);
+        }
     }
 
 private:
@@ -401,10 +419,14 @@ public:
 protected:
     bool executeImpl()
     {
+        mLogger(Trace) << FUNLOG;
+        if (!mSourceSession)
+        {
+            mLogger(Trace) << FUNLOG <<  " Source session is nil, returning early with true";
+            return true;
+        }
         try
         {
-            mLogger(Trace) << FUNLOG;
-
             ConnectedLinePtr currentConnectedLine;
             SessionWrapperPtr sourceWrapper = mBridge->getSessions()->getSession(mSourceSession);
             bool isSet = sourceWrapper->getConnectedLine(currentConnectedLine);
@@ -420,13 +442,20 @@ protected:
             for(SessionSeq::iterator i = sessions.begin();
                 i != sessions.end(); ++i)
             {
-                if ((*i)->ice_getIdentity() == mSourceSession->ice_getIdentity())
+                if (!(*i) || (*i)->ice_getIdentity() == mSourceSession->ice_getIdentity())
                 {
                     continue;
                 }
 
                 SessionWrapperPtr destSessionWrapper = mBridge->getSessions()->getSession(*i);
-                forward(destSessionWrapper, currentConnectedLine);
+                if (destSessionWrapper)
+                {
+                    forward(destSessionWrapper, currentConnectedLine);
+                }
+                else
+                {
+                    mLogger(Debug) << " Destination wrapper for session does not exist, continuing";
+                }
             }
 
         }
@@ -447,30 +476,37 @@ protected:
 
         PartyIdHooksPtr partyIdHooks = mBridge->getPartyIdHooks();
 
-        // Allow the ForwardingConnectedLinePartyId hooks to alter the ConnectedLine record. 
-        for(vector<ForwardingConnectedLinePartyIdHookPrx>::const_iterator i = partyIdHooks->forwardingConnectedLineHooks.begin();
-            i != partyIdHooks->forwardingConnectedLineHooks.end(); ++i)
+        if (partyIdHooks)
         {
-            try
+            // Allow the ForwardingConnectedLinePartyId hooks to alter the ConnectedLine record. 
+            for(vector<ForwardingConnectedLinePartyIdHookPrx>::const_iterator i = partyIdHooks->forwardingConnectedLineHooks.begin();
+                i != partyIdHooks->forwardingConnectedLineHooks.end(); ++i)
             {
-                // Apply a hook
-                AsteriskSCF::System::Hook::V1::HookResult hookResult = (*i)->modifyForwardingConnectedLine(mSourceSession,
-                    destinationSession->getSession(),
-                    currentConnectedLine, destSpecificConnectedLine);
-
-                if (hookResult.status == AsteriskSCF::System::Hook::V1::Succeeded)
+                try
                 {
-                    currentConnectedLine = destSpecificConnectedLine;
+                    // Apply a hook
+                    AsteriskSCF::System::Hook::V1::HookResult hookResult = (*i)->modifyForwardingConnectedLine(mSourceSession,
+                        destinationSession->getSession(),
+                        currentConnectedLine, destSpecificConnectedLine);
+
+                    if (hookResult.status == AsteriskSCF::System::Hook::V1::Succeeded)
+                    {
+                        currentConnectedLine = destSpecificConnectedLine;
+                    }
+                }
+                catch (const std::exception& e)
+                {
+                    mLogger(Debug) << FUNLOG << " : " << e.what();
                 }
-            }
-            catch (const std::exception& e)
-            {
-                mLogger(Debug) << FUNLOG << " : " << e.what();
             }
         }
 
-        // Forward the info via the SessionController for this session.
-        destinationSession->getSessionController()->updateConnectedLine(currentConnectedLine);
+        SessionControllerPrx sessionController = destinationSession->getSessionController();
+        if (sessionController)
+        {
+            // Forward the info via the SessionController for this session.
+            sessionController->updateConnectedLine(currentConnectedLine);
+        }
     }
 
 private:
@@ -497,22 +533,35 @@ public:
 protected:
     bool executeImpl()
     {
+        mLogger(Trace) << FUNLOG;
+        if (!mSource)
+        {
+            mLogger(Trace) << FUNLOG <<  " Source session is nil, returning early with true";
+            return true;
+        }
+
         try
         {
-            mLogger(Trace) << FUNLOG;
 
             // Forward the Caller to each bridged session.
             SessionSeq sessions = mBridge->getSessions()->getSessionSeq();
             for(SessionSeq::iterator i = sessions.begin();
                 i != sessions.end(); ++i)
             {
-                if ((*i)->ice_getIdentity() == mSource->ice_getIdentity())
+                if (!(*i) || (*i)->ice_getIdentity() == mSource->ice_getIdentity())
                 {
                     continue;
                 }
 
                 SessionWrapperPtr destSessionWrapper = mBridge->getSessions()->getSession(*i);
-                forward(destSessionWrapper, mCallerID);
+                if (destSessionWrapper)
+                {
+                    forward(destSessionWrapper, mCallerID);
+                }
+                else
+                {
+                    mLogger(Debug) << " Destination wrapper for session does not exist, continuing";
+                }
             }
 
         }
@@ -524,7 +573,7 @@ protected:
         return true;
     }
            
-    void forward(const SessionWrapperPtr destinationSession, const CallerPtr& callerID)
+    void forward(const SessionWrapperPtr& destinationSession, const CallerPtr& callerID)
     {
         mLogger(Trace) << FUNLOG;
 
@@ -533,30 +582,38 @@ protected:
 
         PartyIdHooksPtr partyIdHooks = mBridge->getPartyIdHooks();
 
-        // Allow the ForwardingConnectedLinePartyId hooks to alter the ConnectedLine record. 
-        for(vector<ForwardingCallerPartyIdHookPrx>::const_iterator i = partyIdHooks->forwardingCallerHooks.begin();
-            i != partyIdHooks->forwardingCallerHooks.end(); ++i)
+        if (partyIdHooks)
         {
-            try
+            // Allow the ForwardingConnectedLinePartyId hooks to alter the ConnectedLine record. 
+            for(vector<ForwardingCallerPartyIdHookPrx>::const_iterator i = partyIdHooks->forwardingCallerHooks.begin();
+                i != partyIdHooks->forwardingCallerHooks.end(); ++i)
             {
-                // Apply a hook
-                AsteriskSCF::System::Hook::V1::HookResult hookResult = (*i)->modifyForwardingCaller(mSource,
-                    destinationSession->getSession(),
-                    currentCallerID, destSpecificCallerID);
-
-                if (hookResult.status == AsteriskSCF::System::Hook::V1::Succeeded)
+                try
                 {
-                    currentCallerID = destSpecificCallerID;
+                    // Apply a hook
+                    AsteriskSCF::System::Hook::V1::HookResult hookResult = (*i)->modifyForwardingCaller(mSource,
+                        destinationSession->getSession(),
+                        currentCallerID, destSpecificCallerID);
+
+                    if (hookResult.status == AsteriskSCF::System::Hook::V1::Succeeded)
+                    {
+                        currentCallerID = destSpecificCallerID;
+                    }
+                }
+                catch (const std::exception& e)
+                {
+                    mLogger(Debug) << FUNLOG << " : " << e.what();
                 }
-            }
-            catch (const std::exception& e)
-            {
-                mLogger(Debug) << FUNLOG << " : " << e.what();
             }
         }
-
+        //
         // Forward the info via the SessionController for this session.
-        destinationSession->getSessionController()->updateCallerID(currentCallerID);
+        //
+        SessionControllerPrx sessionController =  destinationSession->getSessionController();
+        if (sessionController)
+        {
+            sessionController->updateCallerID(currentCallerID);
+        }
     }
 
 private:
@@ -589,31 +646,43 @@ protected:
     bool executeImpl()
     {
         mLogger(Trace) << FUNLOG;
+        if (!mSourceSession)
+        {
+            mLogger(Trace) << FUNLOG << "Source session is nil, returning early with true.";
+            return true;
+        }
 
         ConnectedLinePtr currentConnectedLine = mConnectedLine;
         ConnectedLinePtr updatedConnectedLine = mConnectedLine;
         SessionWrapperPtr wrapper = mBridge->getSessions()->getSession(mSourceSession);
 
-        PartyIdHooksPtr partyIdHooks = mBridge->getPartyIdHooks();
+        if (!wrapper)
+        {
+            mLogger(Debug) << "Unable to find matching session for, returning early with true.";
+        }
 
-        // Allow the ReceivedConnectedLinePartyId hooks to alter the ConnectedLine record. 
-        for(vector<ReceivedConnectedLinePartyIdHookPrx>::const_iterator i = partyIdHooks->receivedConnectedLineHooks.begin();
-            i != partyIdHooks->receivedConnectedLineHooks.end(); ++i)
+        PartyIdHooksPtr partyIdHooks = mBridge->getPartyIdHooks();
+        if (partyIdHooks)
         {
-            try
+            // Allow the ReceivedConnectedLinePartyId hooks to alter the ConnectedLine record. 
+            for(vector<ReceivedConnectedLinePartyIdHookPrx>::const_iterator i = partyIdHooks->receivedConnectedLineHooks.begin();
+                i != partyIdHooks->receivedConnectedLineHooks.end(); ++i)
             {
-                // Apply this hook. 
-                AsteriskSCF::System::Hook::V1::HookResult hookResult = (*i)->modifyReceivedConnectedLine(mSourceSession,
-                    currentConnectedLine, updatedConnectedLine);
-
-                if (hookResult.status == AsteriskSCF::System::Hook::V1::Succeeded)
+                try
                 {
-                    currentConnectedLine = updatedConnectedLine;
+                    // Apply this hook. 
+                    AsteriskSCF::System::Hook::V1::HookResult hookResult = (*i)->modifyReceivedConnectedLine(mSourceSession,
+                        currentConnectedLine, updatedConnectedLine);
+
+                    if (hookResult.status == AsteriskSCF::System::Hook::V1::Succeeded)
+                    {
+                        currentConnectedLine = updatedConnectedLine;
+                    }
+                }
+                catch (const std::exception& e)
+                {
+                    mLogger(Debug) << FUNLOG << " : " << e.what();
                 }
-            }
-            catch (const std::exception& e)
-            {
-                mLogger(Debug) << FUNLOG << " : " << e.what();
             }
         }
 
@@ -1544,7 +1613,6 @@ void BridgeImpl::shutdown(const Ice::Current& current)
         update = createUpdate();
     }
     pushUpdate(update);
-    update = 0;
     {
         //
         // Currently the slice defines the response "Normal Clearing" as the default
@@ -1560,12 +1628,24 @@ void BridgeImpl::shutdown(const Ice::Current& current)
         //
         // Remove references to the session listener implementation.
         //
-        update = createUpdate();
         mObjAdapter->remove(mSessionListenerPrx->ice_getIdentity());
         mSessionListener = 0;
     }
+    
+    try
+    {
+        if (replicate())
+        {
+            Ice::StringSeq keys;
+            keys.push_back(mState->key);
+            mReplicator->removeState(keys);
+        }
+    }
+    catch (const Ice::Exception&)
+    {
+    }
+
     mSessions = 0;
-    pushUpdate(update);
 }
 
 void BridgeImpl::destroy(const Ice::Current& current)
@@ -1596,6 +1676,19 @@ void BridgeImpl::destroy(const Ice::Current& current)
     // Remove references to the session listener implementation.
     //
     mObjAdapter->remove(mSessionListenerPrx->ice_getIdentity());
+
+    try
+    {
+        if (replicate())
+        {
+            Ice::StringSeq keys;
+            keys.push_back(mState->key);
+            mReplicator->removeState(keys);
+        }
+    }
+    catch (const Ice::Exception&)
+    {
+    }
 }
 
 void BridgeImpl::addListener(const BridgeListenerPrx& listener, const Ice::Current& current)
@@ -1634,7 +1727,7 @@ void BridgeImpl::removeListener(const BridgeListenerPrx& listener, const Ice::Cu
     }
     if (mListeners->removeListener(listener))
     {
-        string key = mState->key + ".listener." +
+        string key = mState->bridgeId + ".listener." +
             mObjAdapter->getCommunicator()->identityToString(listener->ice_getIdentity());
         if (replicate())
         {
@@ -1993,7 +2086,7 @@ BridgeStateItemPtr BridgeImpl::createUpdate()
     //
     if (replicate())
     {
-        BridgeStateItemPtr result = new BridgeStateItem(*mState.get());
+        BridgeStateItemPtr result = BridgeStateItemPtr::dynamicCast(mState->ice_clone());
         return result;
     }
     return 0;
@@ -2058,7 +2151,7 @@ AsteriskSCF::BridgeService::BridgeServant::create(const Ice::ObjectAdapterPtr& o
     logger(Trace) << FUNLOG << ": creating replica for " << state->bridgeId;
     IceUtil::Handle<AsteriskSCF::BridgeService::BridgeServant> bridge(
         new BridgeImpl(state->bridgeId, objectAdapter, vector<BridgeListenerPrx>(),
-                    listenerMgr, replicator, state, logger));
+            listenerMgr, replicator, BridgeStateItemPtr::dynamicCast(state->ice_clone()), logger));
     
     return bridge;
 }
diff --git a/src/BridgeManagerImpl.cpp b/src/BridgeManagerImpl.cpp
index 9d2c83f..a12c94c 100644
--- a/src/BridgeManagerImpl.cpp
+++ b/src/BridgeManagerImpl.cpp
@@ -46,6 +46,10 @@ namespace
 #ifndef _NDEBUG
 void dump(const Logger& logger, const BridgeCreationHookDataPtr& hookData)
 {
+    //
+    // TODO: this whole thing should not be run if running at the "Trace"
+    // log level.
+    //
     ostringstream os;
     os << "Hook data:";
     string indent = "   ";
@@ -67,7 +71,7 @@ void dump(const Logger& logger, const BridgeCreationHookDataPtr& hookData)
     {
         os << prefix << indent << indent << (*i);
     }
-    logger(Debug) << os.str();
+    logger(Trace) << os.str();
 }
 #else
 void dump(const Logger&, const BridgeCreationHookDataPtr&)
@@ -124,7 +128,7 @@ public:
 
     void createBridgeReplica(const BridgeStateItemPtr& bridgeState);
 
-    void removeBridge(const BridgeStateItemPtr& bridgeState);
+    void removeBridge(const string& bridgeState);
 
 private:
 
@@ -484,13 +488,7 @@ void BridgeManagerImpl::updateState(const BridgeManagerStateItemPtr& state)
 {
     mLogger(Trace) << FUNLOG;
     boost::unique_lock<boost::shared_mutex> lock(mLock);
-    //
-    // We perform a deep copy because there are no guarantees about the thread safety of the memory
-    // pointed to be "state" over time. We could "say" that the call acquires ownership, but its
-    // safer to take the added cost of the copy.
-    //
-    *mState = *state;
-
+    mState = BridgeManagerStateItemPtr::dynamicCast(state->ice_clone());
     mPartyIdExtensionPoint->replaceHooks(state->partyIdExtensionPointHooks);
 }
 
@@ -561,13 +559,13 @@ void BridgeManagerImpl::createBridgeReplica(const BridgeStateItemPtr& state)
     mBridges.push_back(info);
 }
 
-void BridgeManagerImpl::removeBridge(const BridgeStateItemPtr& state)
+void BridgeManagerImpl::removeBridge(const string& bridgeId)
 {
     mLogger(Trace) << FUNLOG;
     boost::unique_lock<boost::shared_mutex> lock(mLock);
     for (vector<BridgeInfo>::iterator i = mBridges.begin(); i != mBridges.end(); ++i)
     {
-        if (i->servant->id() == state->bridgeId)
+        if (i->servant->id() == bridgeId)
         {
             i->servant->destroyImpl();
             mBridges.erase(i);
diff --git a/src/BridgeManagerImpl.h b/src/BridgeManagerImpl.h
index ff2f6ae..ab2b6aa 100644
--- a/src/BridgeManagerImpl.h
+++ b/src/BridgeManagerImpl.h
@@ -56,7 +56,7 @@ public:
 
     virtual void createBridgeReplica(const AsteriskSCF::Replication::BridgeService::V1::BridgeStateItemPtr& bridgeState) = 0;
 
-    virtual void removeBridge(const AsteriskSCF::Replication::BridgeService::V1::BridgeStateItemPtr& bridgeState) = 0;
+    virtual void removeBridge(const std::string& bridgeId) = 0;
 };
 
 typedef IceUtil::Handle<BridgeManagerServant> BridgeManagerServantPtr;
diff --git a/src/BridgeReplicatorStateListenerI.cpp b/src/BridgeReplicatorStateListenerI.cpp
index fcbd5bf..97ebf96 100644
--- a/src/BridgeReplicatorStateListenerI.cpp
+++ b/src/BridgeReplicatorStateListenerI.cpp
@@ -41,18 +41,40 @@ public:
     {
     }
 
+    void removeBridgeItem(const string& bridgeKey, const string& item, const string& sliceType)
+    {
+        IceUtil::Mutex::Lock lock(mMutex);
+        mLogger(Trace) << " removing bridge item id " << item << " (" << sliceType << ") from bridge " << bridgeKey;
+        mBridgeItemMap[bridgeKey].erase(item);
+        if (mBridgeItemMap[bridgeKey].empty())
+        {
+            map<string, ReplicatedStateItemPtr>::iterator entry = mItems.find(bridgeKey);
+            if (entry == mItems.end())
+            {
+                mLogger(Trace) << "no items left, and the bridge itself is no longer in item dictionary, it is safe to remove the bridge";
+                mManager->removeBridge(bridgeKey);
+            }
+        }
+    }
+
     void stateRemoved(const Ice::StringSeq& itemKeys, const Ice::Current& current)
     {
         for (Ice::StringSeq::const_iterator k = itemKeys.begin(); k != itemKeys.end(); ++k)
         {
-
-            map<string, ReplicatedStateItemPtr>::iterator entry =  mItems.find((*k));
-            if (entry != mItems.end())
+            ReplicatedStateItemPtr item;
+            {
+                IceUtil::Mutex::Lock lock(mMutex);
+                map<string, ReplicatedStateItemPtr>::iterator entry = mItems.find((*k));
+                if (entry != mItems.end())
+                {
+                    item = entry->second;
+                    mItems.erase(entry);
+                }
+            }
+            if (item)
             {
-                ReplicatedStateItemPtr item = entry->second;
                 mLogger(Trace) << " received removal of " << (*k) << ": a " << item->ice_id();
 
-                mItems.erase(entry);
                 BridgedSessionPtr bridgedSessionItem = BridgedSessionPtr::dynamicCast(item);
                 if (bridgedSessionItem)
                 {
@@ -68,6 +90,7 @@ public:
                             // Keep the session list clean.
                             //
                             found = true;
+                            removeBridgeItem(bridgedSessionItem->bridgeId, bridgedSessionItem->key, item->ice_id());
                         }
                         //
                         // We could break here if we could be sure that there were no other updates.
@@ -85,6 +108,7 @@ public:
                         if ((*b) && (*b)->id() == bridgeListener->bridgeId)
                         {
                             (*b)->removeListener(bridgeListener);
+                            removeBridgeItem(bridgeListener->bridgeId, bridgeListener->key, item->ice_id());
                         }
                         //
                         // We could break here if we could be sure that there were no other updates.
@@ -100,13 +124,23 @@ public:
                     {
                         dumpState(cerr, bridgeItem, current.adapter->getCommunicator());
                     }
-                    mManager->removeBridge(bridgeItem);
+                    if (mBridgeItemMap[bridgeItem->bridgeId].empty())
+                    {
+                        mManager->removeBridge(bridgeItem->bridgeId);
+                    }
                     continue;
                 }
 
                 //
                 // Session pairings are cleaned up by way of sessions going away.
                 //
+                SessionPairingPtr pairing = SessionPairingPtr::dynamicCast(item);
+                if (pairing)
+                {
+                    removeBridgeItem(pairing->bridgeKey, pairing->key, item->ice_id());
+                    continue;
+                }
+
 
                 ///
                 // The bridge manager isn't really removable.
@@ -121,30 +155,34 @@ public:
         {
             mLogger(Trace) << " received update " << (*i)->serial << " for " << (*i)->key << " (a " <<
                 (*i)->ice_id() << ")";
-            map<string, ReplicatedStateItemPtr>::iterator entry =  mItems.find((*i)->key);
             ReplicatedStateItemPtr existingItem;
-            if (entry != mItems.end())
             {
-                //
-                // Note: Another serial number situation to consider is two updates of the same key with
-                // the same serial number.
-                //
+                IceUtil::Mutex::Lock lock(mMutex);
+                map<string, ReplicatedStateItemPtr>::iterator entry =  mItems.find((*i)->key);
+                if (entry != mItems.end())
+                {
+                    //
+                    // Note: Another serial number situation to consider is two updates of the same key with
+                    // the same serial number.
+                    //
 
-                //
-                // Look at serial numbers and indicate an out of sequence update. We should
-                // ignore out of sequence updates.
-                //
-                if ((entry->second->serial > (*i)->serial) && (*i)->serial > SerialCounterStart)
+                    //
+                    // Look at serial numbers and indicate an out of sequence update. We should
+                    // ignore out of sequence updates.
+                    //
+                    if ((entry->second->serial > (*i)->serial) && (*i)->serial > SerialCounterStart)
+                    {
+                        mLogger(Error) << "Update serial number for " << (*i)->key << " out of sequence! " << 
+                            (*i)->serial << " updating " << entry->second->serial;
+                        continue;
+                    }
+                    existingItem = entry->second;
+                    entry->second = (*i);
+                }
+                else
                 {
-                    mLogger(Error) << "Update serial number for " << (*i)->key << " out of sequence! " << 
-                        (*i)->serial << " updating " << entry->second->serial;
-                    continue;
+                    mItems[(*i)->key] = *i;
                 }
-                existingItem = entry->second;
-            }
-            else
-            {
-                mItems[(*i)->key] = *i;
             }
 
             BridgeManagerStateItemPtr managerItem = BridgeManagerStateItemPtr::dynamicCast((*i));
@@ -181,13 +219,16 @@ public:
                     // We could break here if we could be sure that there were no other updates.
                     //
                 }
-              
 
-                if (!found)
+                //
+                // If a race condition occurs on state updates and a bridge and its replica objects are in the process of
+                // shutting down, we need to avoid attempting a recreation of a replica.
+                //
+                if (!found && (bridgeItem->runningState != ShuttingDown && bridgeItem->runningState != Destroyed))
                 {
                     if (existingItem)
                     {
-                        mLogger(Error) << "Replica listener has a bridge object that the bridge manager "
+                        mLogger(Warning) << "Replica listener has a bridge object that the bridge manager "
                             "does not know about. This likely indicates an error and should be investigated.";
                     }
                     mManager->createBridgeReplica(bridgeItem);
@@ -200,6 +241,7 @@ public:
             {
                 vector<BridgeServantPtr> bridges = mManager->getBridges();
                 bool found = false;
+                string unique = IceUtil::generateUUID();
                 for (vector<BridgeServantPtr>::iterator b = bridges.begin(); b != bridges.end(); ++b)
                 {
                     if ((*b) && (*b)->id() == bridgedSessionItem->bridgeId)
@@ -210,6 +252,7 @@ public:
                         // Keep the session list clean.
                         //
                         found = true;
+                        mBridgeItemMap[bridgedSessionItem->bridgeId][bridgedSessionItem->key] = bridgedSessionItem;
                     }
                     //
                     // We could break here if we could be sure that there were no other updates.
@@ -217,7 +260,8 @@ public:
                 }
                 if (!found)
                 {
-                    mLogger(Error) << "received an update for a session on a bridge that does not exist!";
+                    mLogger(Warning) << "received a " << bridgedSessionItem->ice_id() << " (id: " << bridgedSessionItem->key << ")"
+                                   << " update for a session on a bridge that does not exist: " << bridgedSessionItem->bridgeId;
                 }
              
                 continue;
@@ -241,6 +285,7 @@ public:
                         // Keep the session list clean.
                         //
                         found = true;
+                        mBridgeItemMap[sessionPairing->bridgeKey][sessionPairing->key] = sessionPairing;
                     }
                     //
                     // We could break here if we could be sure that there were no other updates.
@@ -248,7 +293,8 @@ public:
                 }
                 if (!found)
                 {
-                    mLogger(Error) << "received an update for a session on a bridge that does not exist!";
+                    mLogger(Warning) << "received a " << sessionPairing->ice_id() << " (id: " << sessionPairing->key << ")"
+                                   << " update for a session on a bridge that does not exist: " << sessionPairing->bridgeKey;
                 }
              
                 continue;
@@ -264,6 +310,8 @@ public:
                     if ((*b) && (*b)->id() == bridgeListener->bridgeId)
                     {
                         (*b)->addListener(bridgeListener);
+                        mBridgeItemMap[bridgeListener->bridgeId][bridgeListener->key] = bridgeListener;
+                        found = true;
                     }
                     //
                     // We could break here if we could be sure that there were no other updates.
@@ -271,21 +319,23 @@ public:
                 }
                 if (!found)
                 {
-                    mLogger(Error) << "received an update for a session on a bridge that does not exist!";
+                    mLogger(Warning) << "received a " << bridgeListener->ice_id() << " (id: " << bridgeListener->key << ")"
+                                   << " update for a session on a bridge that does not exist: " << bridgeListener->bridgeId;
                 }
              
                 continue;
             }
 
-            mLogger(Info) << "Bridge replicator service received an unrecognized replication item.";
+            mLogger(Error) << "Bridge replicator service received an unrecognized replication item: " << (*i)->ice_id();
         }
     }
 
 private:
-
+    IceUtil::Mutex mMutex;
     map<string, ReplicatedStateItemPtr> mItems;
     Logger mLogger;
     BridgeManagerServantPtr mManager;
+    map<string, map<string, ReplicatedStateItemPtr> > mBridgeItemMap;
 };
 
 }
diff --git a/src/Component.cpp b/src/Component.cpp
index 3c1de74..3e875f8 100644
--- a/src/Component.cpp
+++ b/src/Component.cpp
@@ -57,7 +57,9 @@ public:
     Component() : 
         AsteriskSCF::Component::Component(lg, 
                                           "BridgeService"),
-        mListeningToReplicator(false)   {}
+        mListeningToReplicator(false)
+    {
+    }
 
 private:
     // Optional base Component notification overrides. 
@@ -120,6 +122,16 @@ void Component::onActivated()
 void Component::onPreInitialize()
 {
     lg(Debug) << "Launching AsteriskSCF Session-Oriented Bridging Service " << getName();
+    Ice::Int logLevel = getCommunicator()->getProperties()->getPropertyAsIntWithDefault(getName() + ".LogLevel", static_cast<Ice::Int>(Debug));
+    if (logLevel >= 0  && logLevel <= static_cast<Ice::Int>(AsteriskSCF::System::Logging::Off))
+    {
+        lg.setLevel(static_cast<AsteriskSCF::System::Logging::Level>(logLevel));
+        mLogger.setLevel(static_cast<AsteriskSCF::System::Logging::Level>(logLevel));
+    }
+    else
+    {
+        mLogger(Error) << "Configuration attempted to set log level to an invalid value.";
+    }
 }
 
 /** 
diff --git a/src/MediaSplicer.cpp b/src/MediaSplicer.cpp
index 0a90b3f..6d69be0 100755
--- a/src/MediaSplicer.cpp
+++ b/src/MediaSplicer.cpp
@@ -233,7 +233,6 @@ public:
     //
     void destroy()
     {
-        SessionPairingPtr newState;
 	vector<OutgoingPairing> outgoing;
 	vector<IncomingPairing> incoming;
         {
@@ -243,9 +242,14 @@ public:
 	    incoming = mIncoming;
             mIncoming.clear();
             mConnected = false;
-            newState = createUpdate();
         }
-        pushUpdate(newState);
+        if (mReplicator)
+        {
+            vector<string> keys;
+            keys.push_back(mKey);
+            mReplicator->removeState(keys);
+            mReplicator = AsteriskSCF::BridgeService::ReplicatorSmartPrx();
+        }
         mLogger(Trace) << FUNLOG << ": unplugging sinks and sources";
 
         //
diff --git a/src/SessionCollection.cpp b/src/SessionCollection.cpp
index bd3f1ff..9b6c815 100644
--- a/src/SessionCollection.cpp
+++ b/src/SessionCollection.cpp
@@ -202,8 +202,11 @@ void SessionCollection::replicaUpdate(const BridgedSessionPtr& session)
 
 void SessionCollection::removeSession(const BridgedSessionPtr& session)
 {
+    SessionWrapperPtr removedSession;
+    {
     boost::unique_lock<boost::shared_mutex> lock(mLock);
     SessionMap::iterator i = mMap.find(session->key);
+    removedSession = i->second;
     if (i != mMap.end())
     {
         mMap.erase(i);
@@ -214,4 +217,23 @@ void SessionCollection::removeSession(const BridgedSessionPtr& session)
     {
 	mSplicer->disableMixing();
     }
+    }
+    if (removedSession)
+    {
+        removedSession->destroy();
+    }
+}
+
+void SessionCollection::destroy()
+{
+    SessionMap copy;
+    {
+        boost::unique_lock<boost::shared_mutex> lock(mLock);
+        copy = mMap;
+        mMap.clear();
+    }
+    for (SessionMap::iterator i = copy.begin(); i != copy.end();)
+    {
+        i->second->destroy();
+    }
 }
diff --git a/src/SessionCollection.h b/src/SessionCollection.h
index a9c0264..16d8649 100644
--- a/src/SessionCollection.h
+++ b/src/SessionCollection.h
@@ -132,6 +132,8 @@ public:
     void replicaUpdate(const AsteriskSCF::Replication::BridgeService::V1::BridgedSessionPtr& bridgedSession);
 
     void removeSession(const AsteriskSCF::Replication::BridgeService::V1::BridgedSessionPtr& bridgedSession);
+
+    void destroy();
     
 private:
 
diff --git a/src/SessionListener.cpp b/src/SessionListener.cpp
index c6571e3..21778b2 100644
--- a/src/SessionListener.cpp
+++ b/src/SessionListener.cpp
@@ -217,6 +217,12 @@ public:
                         mBridgePrx->shutdown();
                     }
                 }
+                catch (const Ice::ObjectNotExistException&)
+                {
+                    //
+                    // The bridge has already gone away... this is okay.
+                    //
+                }
                 catch (const Ice::Exception& ex)
                 {
                     mLogger(Error) << "Unexpected exception when initiating auto shutdown: " << ex.what();
diff --git a/src/SessionWrapper.cpp b/src/SessionWrapper.cpp
index 480a7e8..5996a76 100644
--- a/src/SessionWrapper.cpp
+++ b/src/SessionWrapper.cpp
@@ -491,6 +491,8 @@ void SessionWrapper::setupMedia()
     // basic method.  If we need to prevent this from recurring, then it needs
     // to be in the caller's logic, not here.
     //
+    // TODO: State check
+    //
     mConnector = 0;
     mSplicer->connect(this, mSession->session);
 }
@@ -500,6 +502,9 @@ void SessionWrapper::setConnector(const MediaConnectorPtr& connector)
     mLogger(Trace) << FUNLOG << " for " << mId;
     {
         boost::unique_lock<boost::shared_mutex> lock(mLock);
+        //
+        // TODO: state check?
+        //
         mConnector = connector;
     }
 }
@@ -509,6 +514,9 @@ void SessionWrapper::updateMedia(const SessionPairingPtr& pairings)
     mLogger(Trace) << FUNLOG << " for " << mId;
     boost::unique_lock<boost::shared_mutex> lock(mLock);
 
+    //
+    // TODO: shouldn't the state be checked here?
+    //
     mSplicer->update(pairings);
 
     if (mConnector)
@@ -567,10 +575,15 @@ void SessionWrapper::destroy()
             //
             unplugMedia();
             mSession->currentState = Done;
-            newState = createUpdate();
         }
     }
-    pushUpdate(newState);
+    if (mReplicator)
+    {
+        vector<string> keys;
+        keys.push_back(mSession->key);
+        mReplicator->removeState(keys);
+        mReplicator = AsteriskSCF::BridgeService::ReplicatorSmartPrx();
+    }
 }
 
 bool SessionWrapper::isDestroyed()
@@ -644,7 +657,6 @@ bool SessionWrapper::getConnectedLine(ConnectedLinePtr& connectedLine)
     return true;
 }
 
-
 AsteriskSCF::Replication::BridgeService::V1::BridgedSessionState SessionWrapper::setState(const AsteriskSCF::Replication::BridgeService::V1::BridgedSessionState newState)
 {
     mLogger(Trace) << FUNLOG << ": updating state " << mId;
diff --git a/src/SessionWrapper.h b/src/SessionWrapper.h
index c11a07b..b03acc4 100644
--- a/src/SessionWrapper.h
+++ b/src/SessionWrapper.h
@@ -158,7 +158,7 @@ public:
      * @return true if the connectedLine parameter was set. 
      */
     bool getConnectedLine(AsteriskSCF::SessionCommunications::PartyIdentification::V1::ConnectedLinePtr& connectedLine);
-    
+
 private:
 
     mutable boost::shared_mutex mLock;
diff --git a/test/TestBridging.cpp b/test/TestBridging.cpp
index 75d3f23..69410c3 100644
--- a/test/TestBridging.cpp
+++ b/test/TestBridging.cpp
@@ -335,6 +335,42 @@ typedef IceUtil::Handle<TestEnvironment> TestEnvironmentPtr;
 TestEnvironmentPtr globalTestEnvironment;
 
 //
+// Some tests leave cruft behind if they fail. This helper function cleans out any old bridge
+// objects that may be laying around so we can rely on a certain baseline.
+//
+void cleanupBridges(const AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx& mgr)
+{
+    BridgeSeq bridges = mgr->listBridges();
+    for (BridgeSeq::const_iterator iter = bridges.begin(); iter != bridges.end(); ++iter)
+    {
+        try
+        {
+            (*iter)->shutdown();
+        }
+        catch (const Ice::ObjectNotExistException&)
+        {
+            //
+            // Good!
+            //
+        }
+        catch (const exception& ex)
+        {
+            //
+            // Not great.
+            //
+            cerr << ex.what() << " thrown when cleaning up bridges";
+        }
+        catch (...)
+        {
+            //
+            // Even less great
+            //
+            cerr << "Unknown exception thrown when cleaning up bridges";
+        }
+    }
+}
+
+//
 // Simple helper for initializing Ice and ensuring proper cleanup in the context of a test case.
 //
 class IceEnvironment
@@ -489,6 +525,7 @@ public:
                 addServant(listenerPrx, testAdapter, servant, testEnv.strToIdent(IceUtil::generateUUID()));
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx = env()->primaryBridgeManager();
                 BOOST_CHECK(mgrPrx);
+                cleanupBridges(mgrPrx);
 
                 mgrPrx->addListener(listenerPrx);
                 BOOST_CHECK(servant->stoppingCalls() == 0);
@@ -532,6 +569,7 @@ public:
 
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx = env()->primaryBridgeManager();
                 BOOST_CHECK(mgrPrx);
+                cleanupBridges(mgrPrx);
                 mgrPrx->addListener(listenerPrx);
                 BOOST_CHECK(servant->stoppingCalls() == 0);
                 BOOST_CHECK(servant->stoppedCalls() == 0);
@@ -639,6 +677,7 @@ public:
 
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx = env()->primaryBridgeManager();
                 BOOST_CHECK(mgrPrx);
+                cleanupBridges(mgrPrx);
                 mgrPrx->addListener(listenerPrx);
                 BOOST_CHECK(servant->stoppingCalls() == 0);
                 BOOST_CHECK(servant->stoppedCalls() == 0);
@@ -736,6 +775,7 @@ public:
 
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx = env()->primaryBridgeManager();
                 BOOST_CHECK(mgrPrx);
+                cleanupBridges(mgrPrx);
                 mgrPrx->addListener(listenerPrx);
                 BOOST_CHECK(servant->stoppingCalls() == 0);
                 BOOST_CHECK(servant->stoppedCalls() == 0);
@@ -850,6 +890,7 @@ public:
 
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx = env()->primaryBridgeManager();
                 BOOST_CHECK(mgrPrx);
+                cleanupBridges(mgrPrx);
                 mgrPrx->addListener(listenerPrx);
                 BOOST_CHECK(servant->stoppingCalls() == 0);
                 BOOST_CHECK(servant->stoppedCalls() == 0);
@@ -906,6 +947,7 @@ public:
                 testAdapter->activate();
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx = env()->primaryBridgeManager();
                 BOOST_CHECK(mgrPrx);
+                cleanupBridges(mgrPrx);
                 AsteriskSCF::SessionCommunications::V1::SessionSeq sessions;
                 AsteriskSCF::SessionCommunications::V1::SessionPrx a = channel.getSession("111");
                 a->start();
@@ -990,6 +1032,7 @@ public:
 
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx = env()->primaryBridgeManager();
                 BOOST_CHECK(mgrPrx);
+                cleanupBridges(mgrPrx);
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx2 = env()->standbyBridgeManager();
                 BOOST_CHECK(mgrPrx2);
                 
@@ -1021,39 +1064,6 @@ public:
                 BOOST_CHECK(servant->createCalls() == 2);
                 bridge->shutdown();
                 mgrPrx->removeListener(listenerPrx);
-
-                BridgeSeq bridges = mgrPrx->listBridges();
-
-                // Activate the secondary component so we can 
-                // query it. 
-                ReplicaPrx secondaryReplica = env()->secondaryReplicaControl();
-                ReplicaPrx primaryReplica = env()->primaryReplicaControl();
-                BOOST_CHECK(primaryReplica->isActive() == true);
-
-                primaryReplica->standby();
-                BOOST_CHECK(primaryReplica->isActive() == false);
-
-                secondaryReplica->activate();
-                BOOST_CHECK(secondaryReplica->isActive() == true);
-
-                BridgeSeq bridges2 = mgrPrx2->listBridges();
-                if (bridges.size() != bridges2.size())
-                {
-                    stringstream os;
-                    os << __FILE__ << ':' << __LINE__ << " Bridge count differs, primary: " << bridges.size() << " vs: "
-                        << bridges2.size();
-                    BOOST_MESSAGE(os.str());
-                }
-
-                BOOST_CHECK(bridges.size() == bridges2.size());
-
-                // Set the components back to original state.
-                secondaryReplica->standby();
-                primaryReplica->activate();
-
-                BOOST_CHECK(primaryReplica->isActive() == true);
-                BOOST_CHECK(secondaryReplica->isActive() == false);
-
             }
             catch (const Ice::Exception& ex)
             {
@@ -1094,6 +1104,7 @@ public:
 
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx = env()->primaryBridgeManager();
                 BOOST_CHECK(mgrPrx);
+                cleanupBridges(mgrPrx);
                 mgrPrx->addListener(listenerPrx);
                 BOOST_CHECK(servant->stoppingCalls() == 0);
                 BOOST_CHECK(servant->stoppedCalls() == 0);
@@ -1197,6 +1208,7 @@ public:
 
                 AsteriskSCF::SessionCommunications::V1::BridgeManagerPrx mgrPrx = env()->primaryBridgeManager();
                 BOOST_CHECK(mgrPrx);
+                cleanupBridges(mgrPrx);
                 mgrPrx->addListener(listenerPrx);
                 BOOST_CHECK(servant->stoppingCalls() == 0);
                 BOOST_CHECK(servant->stoppedCalls() == 0);
@@ -1304,6 +1316,7 @@ public:
 
... 514 lines suppressed ...


-- 
asterisk-scf/integration/bridging.git



More information about the asterisk-scf-commits mailing list