[hydra-commits] hydra/bridging.git branch "master" created.

Commits to the Hydra project code repositories hydra-commits at lists.digium.com
Tue Aug 10 00:01:47 CDT 2010


branch "master" has been created
        at  b01714ec9657c3a3147284502376243e061ac12e (commit)

- Log -----------------------------------------------------------------
commit b01714ec9657c3a3147284502376243e061ac12e
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Aug 10 02:29:00 2010 -0230

    Initial commit of bridge service implementation (changes in progress)

diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..2cd72c0
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "slice"]
+	path = slice
+	url = ssh://git@git.asterisk.org/hydra/slice
+[submodule "cmake"]
+	path = cmake
+	url = ssh://git@git.asterisk.org/hydra/cmake
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..19fb36b
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Service locator build system
+
+# Minimum we require is 2.6, any lower and stuff would fail horribly
+cmake_minimum_required(VERSION 2.6)
+
+# Include common Hydra build infrastructure
+include(cmake/Hydra_v4.cmake)
+
+# This project is C++ based and requires a minimum of 3.4
+hydra_project("bridging service" 3.4 CXX)
+
+# Take care of slice definitions
+add_subdirectory(slice EXCLUDE_FROM_ALL)
+
+# Take care of the source code for this project
+add_subdirectory(src)
+
+# Finally take care of the test suite
+add_subdirectory(test)
diff --git a/cmake b/cmake
new file mode 160000
index 0000000..6f93993
--- /dev/null
+++ b/cmake
@@ -0,0 +1 @@
+Subproject commit 6f939932a3c35300208434795e42f5edae14e259
diff --git a/slice b/slice
new file mode 160000
index 0000000..aedc8c1
--- /dev/null
+++ b/slice
@@ -0,0 +1 @@
+Subproject commit aedc8c12e431ba663550f722ad8ab1479535590e
diff --git a/src/BridgeFactoryImpl.cpp b/src/BridgeFactoryImpl.cpp
new file mode 100644
index 0000000..7a2279d
--- /dev/null
+++ b/src/BridgeFactoryImpl.cpp
@@ -0,0 +1,157 @@
+#include "BridgeFactoryImpl.h"
+#include <Ice/ObjectAdapter.h>
+
+namespace Hydra
+{
+namespace BridgeService
+{
+
+   class ShutdownFunctor : public std::unary_function<Hydra::BridgeService::BridgeImplPtr, void>
+   {
+   public:
+      ShutdownFunctor(const Ice::Current& c) :
+          mCurrent(c)
+      {
+      }
+
+      void operator()(Hydra::BridgeService::BridgeImplPtr b) 
+      { 
+         b->shutdown(mCurrent); 
+      }
+
+   private:
+      const Ice::Current mCurrent;
+   };
+
+}; // End of namespace BridgeService
+};// End of namespace Hydra
+
+Hydra::BridgeService::BridgeFactoryImpl::BridgeFactoryImpl(Ice::ObjectAdapterPtr adapter) :
+   mShuttingDown(false),
+   mSuspended(false),
+   mAdapter(adapter)
+{
+    mLogger.getInfoStream() << "Created Hydra Session-Oriented Bridge Factory." << std::endl; 
+}
+
+Hydra::Core::Bridging::V1::BridgePrx Hydra::BridgeService::BridgeFactoryImpl::createBridge(
+  const Hydra::Core::Endpoint::V1::BaseEndpointPtr& ep,
+  const Hydra::Core::Endpoint::V1::EndpointSeq& endpoints,
+  const Hydra::Core::Bridging::V1::BridgeMonitorPrx& mgr,
+  const Ice::Current& current)
+{
+   //
+   // Verify the endpoints are of the correct type before doing anything else.
+   //
+   Hydra::Session::V1::SessionEndpointPtr adminEp(Hydra::Session::V1::SessionEndpointPtr::dynamicCast(ep));
+   if(ep != 0)
+   {
+       if(!adminEp)
+       {
+           throw Hydra::Core::Bridging::V1::UnsupportedEndpoint(ep->id);
+       }
+       if(!checkEndpointId(*ep->id))
+       {
+           throw Hydra::Core::Endpoint::V1::InvalidEndpointId(ep->id);
+       }
+   }
+
+   Hydra::Session::V1::SessionEndpointSeq eps(endpoints.size());
+   for(Hydra::Core::Endpoint::V1::EndpointSeq::const_iterator i = endpoints.begin(); i != endpoints.end(); ++i)
+   {
+      if(*i == 0)
+      {
+          throw Hydra::Core::Bridging::V1::UnsupportedEndpoint(0);
+      }
+      Hydra::Session::V1::SessionEndpointPtr t(Hydra::Session::V1::SessionEndpointPtr::dynamicCast(*i));
+      if(!t)
+      {
+          throw Hydra::Core::Bridging::V1::UnsupportedEndpoint((*i)->id);
+      }
+      if(!t->id || !checkEndpointId(*t->id))
+      {
+          throw Hydra::Core::Endpoint::V1::InvalidEndpointId(t->id);
+      }
+      eps.push_back(t);
+   }
+
+   //
+   // It is arguable that it might be better to do the shutting down check before going through all the casting work. 
+   // This order has been chosen as the work above is actually an argument validation check that will be required
+   // for all running bridges and it was felt that it was better to arrange things so the lock was not obtained
+   // under normal running conditions for the check. The alternative would be to do two locks, one to check the 
+   // shutdown state and then anothert to modify the state.. but that that is probably more costly still.
+   //
+   boost::unique_lock<boost::shared_mutex> lock(mLock);
+   if(mShuttingDown)
+   {
+      throw Hydra::System::Component::V1::ShuttingDown();
+   }
+   if(mSuspended)
+   {
+      throw Hydra::System::Component::V1::Suspended();
+   }
+   reap();
+
+
+   Hydra::BridgeService::BridgeImplPtr bridge = new Hydra::BridgeService::BridgeImpl(adminEp, eps, mgr);
+   Ice::ObjectPrx obj = mAdapter->addWithUUID(bridge);
+   mBridges.push_back(bridge);
+   return Hydra::Core::Bridging::V1::BridgePrx::uncheckedCast(obj);
+}
+
+void Hydra::BridgeService::BridgeFactoryImpl::shutdown(const Ice::Current& current)
+{
+   boost::unique_lock<boost::shared_mutex> lock(mLock);
+   if(mShuttingDown)
+   {
+      return;
+   }
+   if(mSuspended)
+   {
+      throw Hydra::System::Component::V1::Suspended();
+   }
+   mShuttingDown = true;
+   reap();
+   std::for_each(mBridges.begin(), mBridges.end(), Hydra::BridgeService::ShutdownFunctor(current));
+}
+
+void Hydra::BridgeService::BridgeFactoryImpl::suspend(const Ice::Current& current)
+{
+   boost::unique_lock<boost::shared_mutex> lock(mLock);
+   if(mShuttingDown)
+   {
+      throw Hydra::System::Component::V1::ShuttingDown();
+   }
+   if(mSuspended)
+   {
+      return;
+   }
+   mSuspended = true;
+}
+
+void Hydra::BridgeService::BridgeFactoryImpl::resume(const Ice::Current& current)
+{
+   boost::unique_lock<boost::shared_mutex> lock(mLock);
+   if(mShuttingDown)
+   {
+      throw Hydra::System::Component::V1::ShuttingDown();
+   }
+   if(!mSuspended)
+   {
+      return;
+   }
+   mSuspended = false;
+}
+
+void Hydra::BridgeService::BridgeFactoryImpl::reap()
+{
+   for(std::vector<Hydra::BridgeService::BridgeImplPtr>::iterator i = mBridges.begin(); i != mBridges.end(); ++i)
+   {
+      if((*i)->destroyed())
+      {
+	 std::vector<Hydra::BridgeService::BridgeImplPtr>::iterator t = i;
+	 mBridges.erase(t);
+      }
+   }
+}
diff --git a/src/BridgeFactoryImpl.h b/src/BridgeFactoryImpl.h
new file mode 100644
index 0000000..d8f9f47
--- /dev/null
+++ b/src/BridgeFactoryImpl.h
@@ -0,0 +1,53 @@
+#pragma once
+#ifndef __HYDRA_BRIDGE_FACTORY_IMPL_H
+#define __HYDRA_BRIDGE_FACTORY_IMPL_H
+
+#include <Core/Bridging/BridgeServiceIf.h>
+#include <boost/thread/shared_mutex.hpp>
+#include <vector>
+
+#include "BridgeImpl.h"
+#include "Logger.h"
+
+namespace Hydra
+{
+   namespace BridgeService
+{
+   class BridgeFactoryImpl : public Core::Bridging::V1::BridgeFactory
+   {
+   public:
+
+      BridgeFactoryImpl(Ice::ObjectAdapterPtr adapter);
+
+      //
+      // Hydra::Core::Bridging::V1::BridgeFactory Interface
+      //
+      Core::Bridging::V1::BridgePrx createBridge(
+        const Core::Endpoint::V1::BaseEndpointPtr& ep,
+        const Core::Endpoint::V1::EndpointSeq& endpoints,
+        const Core::Bridging::V1::BridgeMonitorPrx& monitor,
+        const Ice::Current& current);
+
+      //
+      // Hydra::System::Component::V1::ComponentService Interface.
+      //
+      void suspend(const Ice::Current& current);
+      void resume(const Ice::Current& current);
+      void shutdown(const Ice::Current& current);
+
+   private:
+
+      boost::shared_mutex mLock;
+      std::vector<BridgeImplPtr> mBridges;
+      bool mShuttingDown;
+      bool mSuspended;
+      Ice::ObjectAdapterPtr mAdapter;
+      Logger mLogger;
+
+      void reap();
+   };
+
+   typedef IceUtil::Handle<BridgeFactoryImpl> BridgeFactoryImplPtr;
+};
+};
+#endif
diff --git a/src/BridgeImpl.cpp b/src/BridgeImpl.cpp
new file mode 100644
index 0000000..8a3f5dc
--- /dev/null
+++ b/src/BridgeImpl.cpp
@@ -0,0 +1,185 @@
+#include "BridgeImpl.h"
+#include <System/Component/ComponentServiceIf.h>
+#include <Ice/LocalException.h>
+
+//
+// TODO:
+// Operations that are performed on all bridge endpoints might be better done as AMI requests.
+// 
+namespace Hydra
+{
+namespace BridgeService
+{
+   class BridgeShutdownFunctor : public std::unary_function<Session::V1::SessionEndpointPtr, void>
+   {
+   public:
+      BridgeShutdownFunctor(const Core::Endpoint::V1::EndpointIdPtr& id, const Session::V1::ResponseCodePtr& responseCode) : 
+         mId(id),
+         mResponseCode(responseCode)
+      {
+      }
+
+      void operator()(const Hydra::Core::Endpoint::V1::BaseEndpointPtr b) 
+      { 
+         if(!b)
+         {
+            Hydra::Session::V1::SessionEndpointPtr p(Hydra::Session::V1::SessionEndpointPtr::dynamicCast(b));
+            assert(p != 0);
+            if(p->callback)
+            {
+               Hydra::Session::V1::SessionEndpointPtr::dynamicCast(b)->callback->terminated(mId, mResponseCode);
+            }
+         }
+      }
+   private:
+      Core::Endpoint::V1::EndpointIdPtr mId;
+      Session::V1::ResponseCodePtr mResponseCode;
+   };
+
+}; // End of namespace BridgeService
+};// End of namespace Hydra
+
+Hydra::BridgeService::BridgeImpl::BridgeImpl(
+  const Hydra::Session::V1::SessionEndpointPtr& adminEp,
+  const Hydra::Session::V1::SessionEndpointSeq& initialEndpoints,
+  const Hydra::Core::Bridging::V1::BridgeMonitorPrx& manager
+  ) :
+   mAdminEndpoint(adminEp),
+   mEndpoints(initialEndpoints),
+   mManager(manager),
+   mAdminEndpointInList(true)
+{
+}
+
+void Hydra::BridgeService::BridgeImpl::addEndpoint(const Hydra::Core::Endpoint::V1::BaseEndpointPtr& ep, const Ice::Current& current)
+{
+   if(ep == 0 || ep->id == 0)
+   {
+      throw Hydra::Core::Endpoint::V1::InvalidEndpointId(new Hydra::Core::Endpoint::V1::EndpointId);
+   }
+
+   if(!checkEndpointId(*ep->id))
+   {
+      throw Hydra::Core::Endpoint::V1::InvalidEndpointId(ep->id);
+   }
+
+   Hydra::Session::V1::SessionEndpointPtr newEndpoint(Hydra::Session::V1::SessionEndpointPtr::dynamicCast(ep));
+   if(!newEndpoint)
+   {
+      throw Hydra::Core::Bridging::V1::UnsupportedEndpoint(ep->id);
+   }
+   boost::unique_lock<boost::shared_mutex> lock(mLock);
+   statePreCheck();
+   Hydra::Session::V1::SessionEndpointSeq::iterator  i = find(ep->id);
+   if(i != mEndpoints.end())
+   {
+      throw Hydra::Core::Bridging::V1::EndpointAlreadyRegistered();
+   }
+   mEndpoints.push_back(newEndpoint);
+}
+
+void Hydra::BridgeService::BridgeImpl::removeEndpoint(const Hydra::Core::Endpoint::V1::EndpointIdPtr& ep, const Ice::Current& current)
+{
+   boost::unique_lock<boost::shared_mutex> lock(mLock);
+   statePreCheck();
+   Hydra::Session::V1::SessionEndpointSeq::iterator  i = find(ep);
+
+   if(mManager && !mManager->onRemoveEndpoint(*i))
+   {
+      return;
+   }
+   mEndpoints.erase(i);
+}
+
+Hydra::Core::Endpoint::V1::EndpointSeq Hydra::BridgeService::BridgeImpl::listEndpoints(const Ice::Current& current)
+{
+   boost::shared_lock<boost::shared_mutex> lock(mLock);
+   statePreCheck();
+
+   Hydra::Core::Endpoint::V1::EndpointSeq eps;
+   if(mAdminEndpointInList && mAdminEndpoint)
+   {
+      eps.push_back(mAdminEndpoint);
+   }
+   for(Hydra::Session::V1::SessionEndpointSeq::const_iterator i = mEndpoints.begin(); i != mEndpoints.end(); ++i)
+   {
+      eps.push_back(*i);
+   }
+   return eps;
+}
+
+void Hydra::BridgeService::BridgeImpl::shutdown(const Ice::Current& current)
+{
+   {
+      boost::unique_lock<boost::shared_mutex> lock(mLock);
+      if(mState == ShuttingDown)
+      {
+	 return;
+      }
+      if(mState == Destroyed)
+      {
+	 throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+      }
+      mState = ShuttingDown;
+   }
+
+   //
+   // TODO: Source ids for bridge generated operations should come from configuration, etc.
+   //
+   Hydra::Core::Endpoint::V1::EndpointIdPtr sourceId;
+   if(mAdminEndpoint)
+   {
+      sourceId = mAdminEndpoint->id;
+   }
+   //
+   // TODO: Response code for termination messages for bridges shutting down should come from configuration
+   //
+   Hydra::Session::V1::ResponseCodePtr response(new Hydra::Session::V1::ResponseCode(0));
+   std::for_each(mEndpoints.begin(), mEndpoints.end(), Hydra::BridgeService::BridgeShutdownFunctor(sourceId, response));
+}
+
+void Hydra::BridgeService::BridgeImpl::destroy(const Ice::Current& current)
+{
+   {
+      boost::unique_lock<boost::shared_mutex> lock(mLock);
+      if(mState == ShuttingDown)
+      {
+	 throw Hydra::System::Component::V1::ShuttingDown();
+      }
+      if(mState == Destroyed)
+      {
+	 throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+      }
+      mState = Destroyed;
+   }
+}
+
+bool Hydra::BridgeService::BridgeImpl::destroyed()
+{
+   boost::shared_lock<boost::shared_mutex> lock(mLock);
+   return mState == Destroyed;
+}
+
+void Hydra::BridgeService::BridgeImpl::statePreCheck()
+{
+   if(mState == ShuttingDown)
+   {
+      throw Hydra::System::Component::V1::ShuttingDown();
+   }
+   if(mState == Destroyed)
+   {
+      throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+   }
+}
+
+Hydra::Session::V1::SessionEndpointSeq::iterator Hydra::BridgeService::BridgeImpl::find(const Core::Endpoint::V1::EndpointIdPtr& e)
+{
+   for(Hydra::Session::V1::SessionEndpointSeq::iterator i = mEndpoints.begin(); i != mEndpoints.end(); ++i)
+   {
+      if(e->endpointManagerId == (*i)->id->endpointManagerId && e->deviceId == (*i)->id->deviceId)
+      {
+	 return i;
+      }
+   }
+   return mEndpoints.end();
+}
diff --git a/src/BridgeImpl.h b/src/BridgeImpl.h
new file mode 100644
index 0000000..3ae280b
--- /dev/null
+++ b/src/BridgeImpl.h
@@ -0,0 +1,75 @@
+#pragma once
+#ifndef __HYDRA_BRIDGE_SERVICE_IMPL_H
+#define __HYDRA_BRIDGE_SERVICE_IMPL_H
+
+#include <Core/Bridging/BridgeServiceIf.h>
+#include <Session/SessionIf.h>
+#include <boost/thread/shared_mutex.hpp>
+#include <vector>
+
+namespace Hydra
+{
+namespace BridgeService
+{
+    inline bool checkEndpointId(const Core::Endpoint::V1::EndpointId& e)
+    {
+        if(e.endpointManagerId.size() == 0 || e.deviceId.size() == 0)
+        {
+            return false;
+        }
+        return true;
+    }
+
+   //
+   // BridgeImpl is a session oriented bridge. 
+   //
+   class BridgeImpl : public Core::Bridging::V1::Bridge
+   {
+   public:
+      BridgeImpl(const Session::V1::SessionEndpointPtr& adminEp, const Session::V1::SessionEndpointSeq& initialEndpoints,
+        const Core::Bridging::V1::BridgeMonitorPrx& manager);
+
+      //
+      // Hydra::Core::Bridging::Bridge Interface
+      //
+      void addEndpoint(const Core::Endpoint::V1::BaseEndpointPtr& ep, const Ice::Current& current);
+      void removeEndpoint(const Core::Endpoint::V1::EndpointIdPtr& ep, const Ice::Current& current);
+      Core::Endpoint::V1::EndpointSeq listEndpoints(const Ice::Current& current);
+      void shutdown(const Ice::Current& current);
+      void destroy(const Ice::Current& current);
+
+      //
+      // Internal methods
+      //
+      bool destroyed();
+
+   private:
+      boost::shared_mutex mLock;
+      enum ServiceStates
+      { 
+         Starting, 
+         Running, 
+         ShuttingDown, 
+         Destroyed 
+      };
+      ServiceStates mState;
+
+      Core::Endpoint::V1::BaseEndpointPtr mAdminEndpoint;
+      Session::V1::SessionEndpointSeq mEndpoints;
+      Core::Bridging::V1::BridgeMonitorPrx mManager;
+      Core::Bridging::V1::BridgeEventsPrx mEvents;
+
+      //
+      // Policy values.
+      //
+      bool mAdminEndpointInList;
+
+      void statePreCheck();
+      Session::V1::SessionEndpointSeq::iterator find(const Core::Endpoint::V1::EndpointIdPtr& e);
+   };
+
+   typedef IceUtil::Handle<BridgeImpl> BridgeImplPtr;
+} // End of namespace Bridging.
+} // End of namespace Hydra.
+
+#endif 
diff --git a/src/BridgeServiceImpl.h b/src/BridgeServiceImpl.h
new file mode 100644
index 0000000..cca9add
--- /dev/null
+++ b/src/BridgeServiceImpl.h
@@ -0,0 +1,15 @@
+#pragma once
+#ifndef __HYDRA_BRIDGE_SERVICE_IMPL_H
+#define __HYDRA_BRIDGE_SERVICE_IMPL_H
+
+#include <Hydra/Telephony/Bridging/BridgeService.h>
+
+namespace Hydra
+{
+   namespace BridgeService
+   {
+      class BridgeImpl
+   }
+}
+
+#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..bd446ac
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,12 @@
+hydra_component_init(bridgeservice CXX)
+hydra_component_add_slice(bridgeservice EndpointIf)
+hydra_component_add_slice(bridgeservice ComponentServiceIf)
+hydra_component_add_slice(bridgeservice SessionIf)
+hydra_component_add_slice(bridgeservice BridgeServiceIf)
+hydra_component_add_file(bridgeservice Service.cpp)
+hydra_component_add_file(bridgeservice BridgeImpl.cpp)
+hydra_component_add_file(bridgeservice BridgeFactoryImpl.cpp)
+hydra_component_add_ice_libraries(bridgeservice IceStorm)
+hydra_component_add_boost_libraries(bridgeservice thread)
+hydra_component_build_standalone(bridgeservice)
+hydra_component_install(bridgeservice RUNTIME bin "Bridge Service." Core)
diff --git a/src/Logger.h b/src/Logger.h
new file mode 100644
index 0000000..a4a7f0f
--- /dev/null
+++ b/src/Logger.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <iostream>
+
+namespace Hydra
+{
+namespace BridgeService
+{
+    //
+    // Place holder log stream holder.
+    //
+    class Logger 
+    {
+    public:
+        std::ostream& getTraceStream()
+        {
+            return std::cerr;
+        }
+
+        std::ostream& getErrorStream()
+        {
+            return std::cerr;
+        }
+
+        std::ostream& getDebugStream()
+        {
+            return std::cerr;
+        }
+
+        std::ostream& getInfoStream()
+        {
+            return std::cerr;
+        }
+    };
+} // End of namespace BridgeImpl
+} // End of namespace Hydra
diff --git a/src/Service.cpp b/src/Service.cpp
new file mode 100644
index 0000000..0e3ab33
--- /dev/null
+++ b/src/Service.cpp
@@ -0,0 +1,39 @@
+#include <Ice/Ice.h>
+#include "BridgeFactoryImpl.h"
+
+class BridgingApp : public Ice::Application
+{
+public:
+    BridgingApp();
+
+protected:
+    int run(int, char*[]);
+    void interruptCallback(int);
+
+private:
+};
+
+BridgingApp::BridgingApp()
+{
+}
+
+int BridgingApp::run(int, char*[])
+{
+    Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("Hydra.BridgeService");
+    Hydra::Core::Bridging::V1::BridgeFactoryPtr f(new Hydra::BridgeService::BridgeFactoryImpl(adapter));
+    adapter->add(f, communicator()->stringToIdentity("BridgeFactory"));
+    adapter->activate();
+    communicator()->waitForShutdown();
+    return EXIT_SUCCESS;
+}
+
+void BridgingApp::interruptCallback(int)
+{
+    _exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char* argv[])
+{
+    BridgingApp app;
+    return app.main(argc, argv);
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..7f845c5
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,13 @@
+hydra_component_init(bridging_unit_test CXX)
+include_directories("${CMAKE_SOURCE_DIR}/src")
+hydra_component_add_slice(bridging_unit_test EndpointIf)
+hydra_component_add_slice(bridging_unit_test ComponentServiceIf)
+hydra_component_add_slice(bridging_unit_test SessionIf)
+hydra_component_add_slice(bridging_unit_test BridgeServiceIf)
+hydra_component_add_file(bridging_unit_test TestBridging.cpp)
+hydra_component_add_file(bridging_unit_test "../src/BridgeImpl.cpp")
+hydra_component_add_file(bridging_unit_test "../src/BridgeFactoryImpl.cpp")
+hydra_component_add_boost_libraries(bridging_unit_test unit_test_framework)
+hydra_component_add_boost_libraries(bridging_unit_test thread)
+hydra_component_build_standalone(bridging_unit_test)
+hydra_component_install(bridging_unit_test RUNTIME bin "Bridging Test Driver." Core)
diff --git a/test/TestBridging.cpp b/test/TestBridging.cpp
new file mode 100644
index 0000000..0665f2c
--- /dev/null
+++ b/test/TestBridging.cpp
@@ -0,0 +1,376 @@
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE BridgingTestSuite
+#define BOOST_TEST_NO_MAIN
+
+#include <BridgeImpl.h>
+#include <BridgeFactoryImpl.h>
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/debug.hpp>
+#include <Session/SessionIf.h>
+
+#include <Ice/Ice.h>
+
+/* Cache the command line arguments so that Ice can be initialized within the global fixture. */
+struct ArgCacheType
+{
+public:
+   int argc;
+   char **argv;
+};
+static ArgCacheType mCachedArgs;
+
+/**
+ * A global fixture for Ice initialization.
+ * Provides setup/teardown for the entire set of tests.
+ */
+struct GlobalTestFixture
+{
+   GlobalTestFixture()
+   {
+      BOOST_TEST_MESSAGE("Setting up bridging test fixture");
+
+      ::boost::debug::detect_memory_leaks(false);
+      ::boost::unit_test::unit_test_log.set_stream( std::cout );
+   } 
+
+   ~GlobalTestFixture()
+   {
+      BOOST_TEST_MESSAGE("Tearing down bridging test fixture");
+   }
+};
+
+BOOST_GLOBAL_FIXTURE(GlobalTestFixture);
+
+/**
+ * Implement our own main to intercept the command line args.
+ * (A default main() is provided if we hadn't set BOOST_TEST_NO_MAIN at the top of file.)
+ * NOTE: Pass in --log_level=message to see the debug print statements.
+ */
+int BOOST_TEST_CALL_DECL main( int argc, char* argv[] )
+{
+   mCachedArgs.argc = argc;
+   mCachedArgs.argv = argv;
+   return ::boost::unit_test::unit_test_main( &init_unit_test, argc, argv );
+}
+
+BOOST_AUTO_TEST_CASE(BridgeEndpointValidationAddInvalidType)
+{
+   Hydra::BridgeService::BridgeImplPtr b(new Hydra::BridgeService::BridgeImpl(0, Hydra::Session::V1::SessionEndpointSeq(), 0));
+   try
+   {
+       Hydra::Core::Endpoint::V1::BaseEndpointPtr p(new Hydra::Core::Endpoint::V1::BaseEndpoint);
+       p->id = new Hydra::Core::Endpoint::V1::EndpointId;
+       p->id->endpointManagerId = "foo";
+       p->id->deviceId = "bar";
+       b->addEndpoint(p, Ice::Current());
+       BOOST_CHECK("Should not have succeeded" == 0);
+   }
+   catch(Hydra::Core::Bridging::V1::UnsupportedEndpoint&)
+   {
+      BOOST_CHECK(true);
+   }
+}
+
+BOOST_AUTO_TEST_CASE(BridgeEndpointValidationAddInvalidValue)
+{
+   Hydra::BridgeService::BridgeImplPtr b(new Hydra::BridgeService::BridgeImpl(0, Hydra::Session::V1::SessionEndpointSeq(), 0));
+   try
+   {
+      b->addEndpoint(0, Ice::Current());
+      BOOST_CHECK("Should not have succeeded" == 0);
+   }
+   catch(Hydra::Core::Endpoint::V1::InvalidEndpointId&)
+   {
+      BOOST_CHECK(true);
+   }
+}
+
+BOOST_AUTO_TEST_CASE(BridgeEndpointValidationAddValidTypeNullId)
+{
+   Hydra::BridgeService::BridgeImplPtr b(new Hydra::BridgeService::BridgeImpl(0, Hydra::Session::V1::SessionEndpointSeq(), 0));
+   try
+   {
+      Hydra::Session::V1::SessionEndpointPtr p(new Hydra::Session::V1::SessionEndpoint);
+      b->addEndpoint(p, Ice::Current());
+      BOOST_CHECK("Should not have succeeded" == 0);
+   }
+   catch(Hydra::Core::Endpoint::V1::InvalidEndpointId&)
+   {
+      BOOST_CHECK(true);
+   }
+}
+
+BOOST_AUTO_TEST_CASE(BridgeEndpointValidationAddValidTypeInvalidId)
+{
+   Hydra::BridgeService::BridgeImplPtr b(new Hydra::BridgeService::BridgeImpl(0, Hydra::Session::V1::SessionEndpointSeq(), 0));
+   try
+   {
+      Hydra::Session::V1::SessionEndpointPtr p(new Hydra::Session::V1::SessionEndpoint);
+      p->id = new Hydra::Core::Endpoint::V1::EndpointId;
+      p->id->endpointManagerId = "";
+      p->id->deviceId = "";
+      b->addEndpoint(p, Ice::Current());
+      BOOST_CHECK("Should not have succeeded" == 0);
+   }
+   catch(Hydra::Core::Endpoint::V1::InvalidEndpointId& ex)
+   {
+       BOOST_CHECK(ex.badId->endpointManagerId == "");
+       BOOST_CHECK(ex.badId->deviceId == "");
+       BOOST_CHECK(true);
+   }
+}
+
+BOOST_AUTO_TEST_CASE(BridgeEndpointAddValidTypeValidValue)
+{
+   Hydra::BridgeService::BridgeImplPtr b(new Hydra::BridgeService::BridgeImpl(0, Hydra::Session::V1::SessionEndpointSeq(), 0));
+   try
+   {
+      Hydra::Session::V1::SessionEndpointPtr p(new Hydra::Session::V1::SessionEndpoint);
+      p->id = new Hydra::Core::Endpoint::V1::EndpointId;
+      p->id->endpointManagerId = "foo";
+      p->id->deviceId = "bar";
+      b->addEndpoint(p, Ice::Current());
+      BOOST_CHECK(true);
+   }
+   catch(...)
+   {
+       BOOST_CHECK("Unexpected exception thrown!" == 0);
+   }
+}
+
+BOOST_AUTO_TEST_CASE(BridgeEndpointListEp)
+{
+   Hydra::BridgeService::BridgeImplPtr b(new Hydra::BridgeService::BridgeImpl(0, Hydra::Session::V1::SessionEndpointSeq(), 0));
+   try
+   {
+      Hydra::Session::V1::SessionEndpointPtr p(new Hydra::Session::V1::SessionEndpoint);
+      p->id = new Hydra::Core::Endpoint::V1::EndpointId;
+      p->id->endpointManagerId = "foo";
+      p->id->deviceId = "bar";
+      b->addEndpoint(p, Ice::Current());
+      Hydra::Core::Endpoint::V1::EndpointSeq endpoints = b->listEndpoints(Ice::Current());
+      BOOST_CHECK(endpoints.size() == 1);
+      BOOST_CHECK(endpoints.back()->id->endpointManagerId == "foo" && endpoints.back()->id->deviceId == "bar");
+   }
+   catch(...)
+   {
+       BOOST_CHECK("Unexpected exception thrown!" == 0);
+   }
+}
+
+BOOST_AUTO_TEST_CASE(BridgeFactoryCreateBridgeWithInvalidAdminEndpoint)
+{
+    Ice::InitializationData initData;
+    initData.properties = Ice::createProperties(0);
+    initData.properties->setProperty("TestBridging.Endpoints", "default -p 33333 -t 1000");
+    Ice::CommunicatorPtr comm = Ice::initialize(initData);
+    Ice::ObjectAdapterPtr adapter = comm->createObjectAdapter("TestBridging");
+    try
+    {
+        Hydra::BridgeService::BridgeFactoryImplPtr factory(new Hydra::BridgeService::BridgeFactoryImpl(adapter));
+
+        try
+        {
+            Hydra::Core::Endpoint::V1::BaseEndpointPtr p(new Hydra::Core::Endpoint::V1::BaseEndpoint);
+            p->id = new Hydra::Core::Endpoint::V1::EndpointId;
+            p->id->endpointManagerId = "foo";
+            p->id->deviceId = "bar";
+            Hydra::Core::Bridging::V1::BridgePrx b =  factory->createBridge(p, Hydra::Core::Endpoint::V1::EndpointSeq(), 0, Ice::Current());
+            BOOST_CHECK("Should not have succeeded" == 0);
+        }
+        catch(const Hydra::Core::Bridging::V1::UnsupportedEndpoint& x)
+        {
+            BOOST_CHECK(x.ep->endpointManagerId == "foo" && x.ep->deviceId == "bar");
+        }
+    }
+    catch(...)
+    {
+        adapter->destroy();
+        throw;
+    }
+    adapter->destroy();
+}
+
+BOOST_AUTO_TEST_CASE(BridgeFactoryCreateBridgeWithInvalidAdminEndpointId)
+{
+    Ice::InitializationData initData;
+    initData.properties = Ice::createProperties(0);
+    initData.properties->setProperty("TestBridging.Endpoints", "default -p 33333 -t 1000");
+    Ice::CommunicatorPtr comm = Ice::initialize(initData);
+    Ice::ObjectAdapterPtr adapter = comm->createObjectAdapter("TestBridging");
+    try
+    {
+        Hydra::BridgeService::BridgeFactoryImplPtr factory(new Hydra::BridgeService::BridgeFactoryImpl(adapter));
+
+        try
+        {
+            Hydra::Core::Endpoint::V1::BaseEndpointPtr p(new Hydra::Session::V1::SessionEndpoint);
+            p->id = new Hydra::Core::Endpoint::V1::EndpointId;
+            p->id->endpointManagerId = "";
+            p->id->deviceId = "";
+            Hydra::Core::Bridging::V1::BridgeMonitorPrx monitor;
+            Hydra::Core::Bridging::V1::BridgePrx b = factory->createBridge(p, Hydra::Core::Endpoint::V1::EndpointSeq(), 0, Ice::Current());
+            BOOST_CHECK("Should not have succeeded" == 0);
+        }
+        catch(const Hydra::Core::Endpoint::V1::InvalidEndpointId& id)
+        {
+            BOOST_CHECK(true);
+        }
+    }
+    catch(...)
+    {
+        adapter->destroy();
+        throw;
+    }
+    adapter->destroy();
+}
+
+BOOST_AUTO_TEST_CASE(BridgeFactoryCreateBridgeWithValidAdminEndpoint)
+{
+    Ice::InitializationData initData;
+    initData.properties = Ice::createProperties(0);
+    initData.properties->setProperty("TestBridging.Endpoints", "default -p 33333 -t 1000");
+    Ice::CommunicatorPtr comm = Ice::initialize(initData);
+    Ice::ObjectAdapterPtr adapter = comm->createObjectAdapter("TestBridging");
+    try
+    {
+        Hydra::BridgeService::BridgeFactoryImplPtr factory(new Hydra::BridgeService::BridgeFactoryImpl(adapter));
+        Hydra::Core::Endpoint::V1::BaseEndpointPtr p(new Hydra::Session::V1::SessionEndpoint);
+        p->id = new Hydra::Core::Endpoint::V1::EndpointId;
+        p->id->endpointManagerId = "foo";
+        p->id->deviceId = "bar";
+        Hydra::Core::Bridging::V1::BridgeMonitorPrx monitor;
+        Hydra::Core::Bridging::V1::BridgePrx b =  factory->createBridge(p, Hydra::Core::Endpoint::V1::EndpointSeq(), monitor, Ice::Current());
+        BOOST_CHECK(b);
+        Hydra::Core::Endpoint::V1::EndpointSeq endpoints = b->listEndpoints();
+        BOOST_CHECK(endpoints.size() == 1);
+        BOOST_CHECK(endpoints.back()->id->endpointManagerId == "foo" && endpoints.back()->id->deviceId == "bar");
+    }
+    catch(...)
+    {
+        adapter->destroy();
+        throw;
+    }
+    adapter->destroy();
+}
+
+BOOST_AUTO_TEST_CASE(BridgeFactoryEmptyBridge)
+{
+    Ice::InitializationData initData;
+    initData.properties = Ice::createProperties(0);
+    initData.properties->setProperty("TestBridging.Endpoints", "default -p 33333 -t 1000");
+    Ice::CommunicatorPtr comm = Ice::initialize(initData);
+    Ice::ObjectAdapterPtr adapter = comm->createObjectAdapter("TestBridging");
+    try
+    {
+        Hydra::BridgeService::BridgeFactoryImplPtr factory(new Hydra::BridgeService::BridgeFactoryImpl(adapter));
+        Hydra::Core::Bridging::V1::BridgePrx b =  factory->createBridge(0, Hydra::Core::Endpoint::V1::EndpointSeq(), 0, Ice::Current());
+        BOOST_CHECK(b);
+        Hydra::Core::Endpoint::V1::EndpointSeq endpoints = b->listEndpoints();
+        BOOST_CHECK(endpoints.size() == 0);
+    }
+    catch(...)
+    {
+        adapter->destroy();
+        throw;
+    }
+    adapter->destroy();
+}
+
+BOOST_AUTO_TEST_CASE(BridgeFactoryInitialEndpointInvalidType)
+{
+    Ice::InitializationData initData;
+    initData.properties = Ice::createProperties(0);
+    initData.properties->setProperty("TestBridging.Endpoints", "default -p 33333 -t 1000");
+    Ice::CommunicatorPtr comm = Ice::initialize(initData);
+    Ice::ObjectAdapterPtr adapter = comm->createObjectAdapter("TestBridging");
+    try
+    {
+        Hydra::BridgeService::BridgeFactoryImplPtr factory(new Hydra::BridgeService::BridgeFactoryImpl(adapter));
+        Hydra::Core::Endpoint::V1::BaseEndpointPtr p(new Hydra::Core::Endpoint::V1::BaseEndpoint);
+        p->id = new Hydra::Core::Endpoint::V1::EndpointId;
+        p->id->endpointManagerId = "foo";
+        p->id->deviceId = "bar";
+
+        Hydra::Core::Endpoint::V1::EndpointSeq eps;
+        eps.push_back(p);
+
+        Hydra::Core::Bridging::V1::BridgePrx b =  factory->createBridge(0, eps, 0, Ice::Current());
+        BOOST_CHECK("Should not have succeeded" == 0);
+    }
+    catch(const Hydra::Core::Bridging::V1::UnsupportedEndpoint& ex)
+    {
+        BOOST_CHECK(ex.ep->endpointManagerId == "foo" && ex.ep->deviceId == "bar");
+    }
+    catch(...)
+    {
+        adapter->destroy();
+        throw;
+    }
+    adapter->destroy();
+}
+
+BOOST_AUTO_TEST_CASE(BridgeFactoryInitialEndpointNullId)
+{
+    Ice::InitializationData initData;
+    initData.properties = Ice::createProperties(0);
+    initData.properties->setProperty("TestBridging.Endpoints", "default -p 33333 -t 1000");
+    Ice::CommunicatorPtr comm = Ice::initialize(initData);
+    Ice::ObjectAdapterPtr adapter = comm->createObjectAdapter("TestBridging");
+    try
+    {
+        Hydra::BridgeService::BridgeFactoryImplPtr factory(new Hydra::BridgeService::BridgeFactoryImpl(adapter));
+        Hydra::Core::Endpoint::V1::BaseEndpointPtr p(new Hydra::Session::V1::SessionEndpoint);
+        p->id = 0;
+        Hydra::Core::Endpoint::V1::EndpointSeq eps;
+        eps.push_back(p);
+
+        Hydra::Core::Bridging::V1::BridgePrx b =  factory->createBridge(0, eps, 0, Ice::Current());
+        BOOST_CHECK("Should not have succeeded" == 0);
+    }
+    catch(const Hydra::Core::Endpoint::V1::InvalidEndpointId&)
+    {
+        BOOST_CHECK(true);
+    }
+    catch(...)
+    {
+        adapter->destroy();
+        throw;
+    }
+    adapter->destroy();
+}
+
+BOOST_AUTO_TEST_CASE(BridgeFactoryInitialEndpointInvalidId)
+{
+    Ice::InitializationData initData;
+    initData.properties = Ice::createProperties(0);
+    initData.properties->setProperty("TestBridging.Endpoints", "default -p 33333 -t 1000");
+    Ice::CommunicatorPtr comm = Ice::initialize(initData);
+    Ice::ObjectAdapterPtr adapter = comm->createObjectAdapter("TestBridging");
+    try
+    {
+        Hydra::BridgeService::BridgeFactoryImplPtr factory(new Hydra::BridgeService::BridgeFactoryImpl(adapter));
+        Hydra::Core::Endpoint::V1::BaseEndpointPtr p(new Hydra::Session::V1::SessionEndpoint);
+        p->id = new Hydra::Core::Endpoint::V1::EndpointId;
+        p->id->endpointManagerId == "";
+        p->id->deviceId == "bar";
+
+        Hydra::Core::Endpoint::V1::EndpointSeq eps;
+        eps.push_back(p);
+
+        Hydra::Core::Bridging::V1::BridgePrx b =  factory->createBridge(0, eps, 0, Ice::Current());
+        BOOST_CHECK("Should not have succeeded" == 0);
+    }
+    catch(const Hydra::Core::Endpoint::V1::InvalidEndpointId& ex)
+    {
+        BOOST_CHECK(ex.badId != 0);
+        BOOST_CHECK(ex.badId->endpointManagerId.size() == 0 && ex.badId->deviceId == "bar");
+    }
+    catch(...)
+    {
+        adapter->destroy();
+        throw;
+    }
+    adapter->destroy();
+}

-----------------------------------------------------------------------


-- 
hydra/bridging.git




More information about the asterisk-scf-commits mailing list