[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