[asterisk-scf-commits] asterisk-scf/integration/routing.git branch "master" created.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Tue Aug 17 17:05:21 CDT 2010
branch "master" has been created
at bd7338dffa93908ed182f604bdf162a494f2c91c (commit)
- Log -----------------------------------------------------------------
commit bd7338dffa93908ed182f604bdf162a494f2c91c
Author: Ken Hunt <ken.hunt at digium.com>
Date: Tue Aug 17 16:58:54 2010 -0500
Submodules set to server-based repo.
diff --git a/.gitmodules b/.gitmodules
index e69de29..ee3891f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "slice"]
+ path = slice
+ url = git at gitdepot:asterisk-scf/integration/slice
+[submodule "cmake"]
+ path = cmake
+ url = git at gitdepot:asterisk-scf/release/cmake
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..0fd4cb3
--- /dev/null
+++ b/slice
@@ -0,0 +1 @@
+Subproject commit 0fd4cb3a22d7a3993ae64ee5e4ee73f9ae97a64d
commit 17228b0d395adb97e74bf44a72f9ed6da8ae255b
Author: Ken Hunt <ken.hunt at digium.com>
Date: Tue Aug 17 16:57:22 2010 -0500
Cleanup
diff --git a/.gitmodules b/.gitmodules
index 7b720a3..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +0,0 @@
-[submodule "\\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\slice"]
- path = \\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\slice
- url = C:\\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\slice
-[submodule "\\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\cmake"]
- path = \\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\cmake
- url = C:\\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\cmake
commit 2254fc75f840f099f006330bec8c908cfd0c8f82
Author: Ken Hunt <ken.hunt at digium.com>
Date: Tue Aug 17 16:51:37 2010 -0500
Submodule cleanup
diff --git a/.gitmodules b/.gitmodules
index a40c526..7b720a3 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
-[submodule "slice"]
- path = slice
- url = git at gitdepot:hydra/slice
-[submodule "cmake"]
- path = cmake
- url = git at gitdepot:hydra/cmake
+[submodule "\\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\slice"]
+ path = \\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\slice
+ url = C:\\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\slice
+[submodule "\\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\cmake"]
+ path = \\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\cmake
+ url = C:\\Documents and Settings\\Ken Hunt\\My Documents\\Development\\git.hydra\\cmake
commit af8978adeb780582630dac75bdc133fb08f2c005
Author: Ken Hunt <ken.hunt at digium.com>
Date: Tue Aug 17 11:37:14 2010 -0500
Moving submodules.
diff --git a/cmake b/cmake
deleted file mode 160000
index 6f93993..0000000
--- a/cmake
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 6f939932a3c35300208434795e42f5edae14e259
diff --git a/slice b/slice
deleted file mode 160000
index 2886381..0000000
--- a/slice
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 2886381a2c693563ed1a8955e32e4105d6da6fc0
commit a52965f3ae92dc2717f2227b243b264e31788069
Author: Ken Hunt <ken.hunt at digium.com>
Date: Sun Aug 15 19:51:18 2010 -0500
Added test driver.
diff --git a/config/basicrouting.config b/config/basicrouting.config
new file mode 100644
index 0000000..46074bc
--- /dev/null
+++ b/config/basicrouting.config
@@ -0,0 +1,11 @@
+# This is a configuration file for the Basic Routing Service
+
+# Basic routing service
+BasicRoutingServiceAdapter.Endpoints=tcp -p 10054
+
+# Basic routing service admin
+BasicRoutingServiceAdminAdapter.Endpoints=tcp -p 10055
+
+# Endpoints for Icestorm events
+TopicManager.Proxy=HydraIceStorm/TopicManager:default -p 10012
+
diff --git a/config/icestorm.config b/config/icestorm.config
new file mode 100644
index 0000000..62aeb7f
--- /dev/null
+++ b/config/icestorm.config
@@ -0,0 +1,30 @@
+# This is a configuration file used in conjunction with the service discovery test driver
+
+IceBox.Service.IceStorm=IceStormService,34:createIceStorm --Ice.Config=../config/test_icestorm.config
+
+IceStorm.InstanceName=HydraIceStorm
+#
+# This property defines the endpoints on which the IceStorm
+# TopicManager listens.
+#
+IceStorm.TopicManager.Endpoints=default -p 10000
+
+#
+# This property defines the endpoints on which the topic
+# publisher objects listen. If you want to federate
+# IceStorm instances this must run on a fixed port (or use
+# IceGrid).
+#
+IceStorm.Publish.Endpoints=tcp -p 10001:udp -p 10001
+
+#
+# TopicManager Tracing
+#
+# 0 = no tracing
+# 1 = trace topic creation, subscription, unsubscription
+# 2 = like 1, but with more detailed subscription information
+#
+IceStorm.Trace.TopicManager=2
+
+#
+IceStorm.Flush.Timeout=2000
diff --git a/scripts/routing.lua b/scripts/routing.lua
new file mode 100644
index 0000000..3b736df
--- /dev/null
+++ b/scripts/routing.lua
@@ -0,0 +1,24 @@
+
+
+-- Sets a site-specific policy. The default implementation only
+-- supports a "deny" policy which rejects all lookups until
+-- the policy no longer equals "deny".
+function setPolicy(newpolicy)
+ policy = newpolicy
+end
+
+-- Confirm or deny a lookup() procedure.
+-- @param destination The destination being looked up
+-- @return A (potentially) modified destination to allow rerouting.
+-- @return True to allow the lookup or false to deny.
+function confirmLookup(destination)
+ print ("Looking up extension "..destination)
+ return destination
+
+ if (policy == "deny")
+ return false;
+ else
+ return true
+ end
+end
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..8d0b1e7
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Create Basic Routing Service test project.
+hydra_component_init(RoutingTest CXX)
+hydra_component_add_slice(RoutingTest RoutingIf)
+hydra_component_add_slice(RoutingTest ServiceLocatorIf)
+hydra_component_add_file(RoutingTest TestRouting.cpp)
+hydra_component_add_ice_libraries(RoutingTest IceStorm)
+hydra_component_add_boost_libraries(RoutingTest unit_test_framework)
+hydra_component_build_standalone(RoutingTest)
+hydra_component_install(RoutingTest RUNTIME bin "Routing Service Test Driver." Test)
diff --git a/test/TestRouting.cpp b/test/TestRouting.cpp
new file mode 100644
index 0000000..dafa158
--- /dev/null
+++ b/test/TestRouting.cpp
@@ -0,0 +1,212 @@
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE ServiceLocatorTestSuite
+#define BOOST_TEST_NO_MAIN
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/debug.hpp>
+
+#include <Ice/Ice.h>
+
+#include "Core/Routing/RoutingIf.h"
+#include "Core/Discovery/ServiceLocatorIf.h"
+
+using namespace std;
+using namespace Hydra::Core::Routing::V1;
+using namespace Hydra::Core::Endpoint::V1;
+
+/**
+ * A locator for our test channel's endpoints.
+ */
+typedef EndpointSeq::iterator EndpointIterator;
+class TestEndpointLocatorImpl : public EndpointLocator
+{
+public:
+ EndpointSeq lookup(const ::std::string& destination, const Ice::Current&)
+ {
+ EndpointSeq endpoints;
+
+ for (EndpointIterator e=mEndpoints.begin(); e!= mEndpoints.end(); e++)
+ {
+ BaseEndpointPtr ep = *e;
+ if ((*e)->id->destinationId == destination)
+ {
+ endpoints.push_back(*e);
+ }
+ }
+
+ if (endpoints.size() == 0)
+ {
+ throw DestinationNotFoundException(destination);
+ }
+ return endpoints;
+ }
+
+ EndpointSeq mEndpoints;
+};
+typedef ::IceInternal::Handle<TestEndpointLocatorImpl> TestEndpointLocatorImplPtr;
+
+/* 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;
+
+/**
+ * It seems odd that boost doesn't provide an easy way to access the GLOBAL_FIXTURE members.
+ * But it doesn't seem to, so I'm sharing global setup stuff here.
+ */
+struct SharedTestData
+{
+public:
+ // Communicator for outgoing stuff
+ Ice::CommunicatorPtr communicator_outgoing;
+
+ // Communicator for incoming stuff
+ Ice::CommunicatorPtr communicator_incoming;
+
+ Ice::ObjectAdapterPtr adapter;
+
+ //A proxy to the actual routing service
+ LocatorRegistryPrx locatorRegistry;
+
+ // Our own EndpointLocator to server up endpoints to the RoutingService, emulating a channel.
+ TestEndpointLocatorImplPtr mEndpointLocator;
+ EndpointLocatorPrx mEndpointLocatorPrx;
+ //std::vector<const std::string> mRegExIds;
+ RegExSeq mRegExIds;
+};
+static SharedTestData Testbed;
+
+/**
+ * A global fixture for Ice initialization.
+ * Provides setup/teardown for the entire set of tests.
+ */
+struct GlobalIceFixture
+{
+ GlobalIceFixture()
+ {
+ BOOST_TEST_MESSAGE("Setting up Basic Rounting Service test fixture");
+
+ ::boost::debug::detect_memory_leaks(false);
+ ::boost::unit_test::unit_test_log.set_stream( std::cout );
+
+ int status = 0;
+ try
+ {
+ Testbed.communicator_incoming = Ice::initialize(mCachedArgs.argc, mCachedArgs.argv);
+
+ //Ice::ObjectFactoryPtr baseEndpointFactory = new BaseEndpointFactory();
+ //Testbed.communicator_incoming->addObjectFactory(baseEndpointFactory, Hydra::Core::Endpoint::V1::BaseEndpoint::ice_staticId());
+
+ // Serve up our own EndpointLocator, since we're emulating a channel.
+ TestEndpointLocatorImpl *locator = new TestEndpointLocatorImpl();
+ Testbed.mEndpointLocator = locator;
+ Testbed.adapter->add(Testbed.mEndpointLocator, Testbed.communicator_incoming->stringToIdentity("Locator"));
+
+
+ // Get ref to Routing Service so we can test it. Getting direct for now, but
+ // need to test acquiring reference via ServiceLocator as well.
+ Ice::ObjectPrx base = Testbed.communicator_incoming->stringToProxy("RoutingServiceLocatorRegistry:default -p 10047");
+ LocatorRegistryPrx server = LocatorRegistryPrx::checkedCast(base);
+
+ Testbed.adapter = Testbed.communicator_incoming->createObjectAdapterWithEndpoints("RoutingServiceAdapter", "default");
+ Testbed.adapter->activate();
+
+ // Now that the adapter has been activated, get a local proxy to our EndpointLocator.
+ Ice::ObjectPrx locatorObjectPrx = Testbed.adapter->createDirectProxy(Testbed.communicator_incoming->stringToIdentity("Locator"));
+ Testbed.mEndpointLocatorPrx = EndpointLocatorPrx::checkedCast(locatorObjectPrx);
+
+ PopulateEndpoints();
+
+ if (!Testbed.locatorRegistry)
+ {
+ throw "Invalid service proxy";
+ }
+ }
+ catch (const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = 1;
+ }
+ catch (const char* msg)
+ {
+ cerr << msg << endl;
+ status = 1;
+ }
+
+ } // end Fixture() constructor
+
+ void PopulateEndpoints()
+ {
+ Testbed.mEndpointLocator->mEndpoints.clear();
+
+ BaseEndpointPtr endpoint = new BaseEndpoint();
+ endpoint->id = new EndpointId("TestChannel", "101");
+ Testbed.mEndpointLocator->mEndpoints.push_back(endpoint);
+
+ endpoint->id = new EndpointId("TestChannel", "102");
+ Testbed.mEndpointLocator->mEndpoints.push_back(endpoint);
+
+ endpoint->id = new EndpointId("TestChannel", "103");
+ Testbed.mEndpointLocator->mEndpoints.push_back(endpoint);
+
+ // Initialize the regular expressions for the ids that this channel will support.
+ // Use two strings just for kicks.
+ Testbed.mRegExIds.push_back("101");
+ Testbed.mRegExIds.push_back("10[23]"); // 102 or 103
+ }
+
+ ~GlobalIceFixture()
+ {
+ BOOST_TEST_MESSAGE("Tearing down service discovery test fixture");
+
+
+ if (Testbed.communicator_incoming)
+ {
+ Testbed.communicator_incoming->shutdown();
+ Testbed.communicator_incoming = 0;
+ }
+ if (Testbed.communicator_outgoing)
+ {
+ Testbed.communicator_outgoing->shutdown();
+ Testbed.communicator_outgoing = 0;
+ }
+ }
+private:
+
+};
+
+BOOST_GLOBAL_FIXTURE(GlobalIceFixture);
+
+/**
+ * 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 );
+}
+
+/**
+ * Confirm that we find no service using locate before we have added one.
+ */
+BOOST_AUTO_TEST_CASE(MyFirstTest)
+{
+ bool succeeded(true);
+ try
+ {
+ Testbed.locatorRegistry->addEndpointLocator("TestChannel", Testbed.mRegExIds, Testbed.mEndpointLocatorPrx);
+ }
+ catch (...)
+ {
+ succeeded = false;
+ }
+
+ BOOST_CHECK(succeeded);
+}
commit 6fa7b2f7cc34abd24d960e33925042f08e492c3f
Author: Ken Hunt <ken.hunt at digium.com>
Date: Sun Aug 15 19:48:20 2010 -0500
Updates for test.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9c83d1b..dcd7f19 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,4 +16,4 @@ add_subdirectory(slice)
add_subdirectory(src)
# Finally take care of the test suite
-#add_subdirectory(test)
+add_subdirectory(test)
diff --git a/src/BasicRoutingServiceApp.cpp b/src/BasicRoutingServiceApp.cpp
index 69fc11d..3cddc8f 100644
--- a/src/BasicRoutingServiceApp.cpp
+++ b/src/BasicRoutingServiceApp.cpp
@@ -4,7 +4,7 @@
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
-#include "BasicRoutingServiceApp.h"
+#include "BasicRoutingServiceDataModel.h"
#include "RoutingIf.h"
#include "LuaScriptProcessor.h"
#include "RoutingServiceEventPublisher.h"
diff --git a/src/BasicRoutingServiceApp.h b/src/BasicRoutingServiceDataModel.h
similarity index 100%
rename from src/BasicRoutingServiceApp.h
rename to src/BasicRoutingServiceDataModel.h
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4ca784c..4c14ab1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,7 +6,7 @@ LINK_DIRECTORIES(${LUA_LOC})
include_directories(${LUA_INCLUDE_DIR})
hydra_component_add_slice(BasicRoutingService RoutingIf)
hydra_component_add_file(BasicRoutingService BasicRoutingServiceApp.cpp)
-hydra_component_add_file(BasicRoutingService BasicRoutingServiceApp.h)
+hydra_component_add_file(BasicRoutingService BasicRoutingServiceDataModel.h)
hydra_component_add_file(BasicRoutingService RoutingAdmin.cpp)
hydra_component_add_file(BasicRoutingService RoutingAdmin.h)
hydra_component_add_file(BasicRoutingService EndpointRegistry.cpp)
diff --git a/src/EndpointRegistry.cpp b/src/EndpointRegistry.cpp
index 82316a3..80d9081 100644
--- a/src/EndpointRegistry.cpp
+++ b/src/EndpointRegistry.cpp
@@ -1,5 +1,7 @@
#include <boost/regex.hpp>
+#include "BasicRoutingServiceDataModel.h"
+#include "RoutingServiceEventPublisher.h"
#include "EndpointRegistry.h"
#include "ScriptProcessor.h"
@@ -15,7 +17,8 @@ struct RegisteredLocator
{
public:
RegisteredLocator() {};
- RegisteredLocator(EndpointLocatorPrx l, const RegExSeq &inputStringList) : locator(l)
+ RegisteredLocator(EndpointLocatorPrx l, const RegExSeq &inputStringList)
+ : locator(l)
{
setRegEx(inputStringList);
}
@@ -44,8 +47,13 @@ public:
class EndpointRegistryPriv
{
public:
+ EndpointRegistryPriv() : mEventPublisher(BasicRoutingServiceDataModel::getInstance().getEventPublisher())
+ {
+ }
+
map<std::string, RegisteredLocator> mEndpointLocatorMap;
boost::shared_ptr<ScriptProcessor> mScriptProcessor;
+ const RoutingServiceEventPublisher& mEventPublisher;
};
typedef map<std::string, RegisteredLocator>::iterator EndpointLocatorMapIterator;
@@ -72,17 +80,20 @@ void EndpointRegistry::addEndpointLocator(const ::std::string& locatorId,
EndpointLocatorMapIterator existing = mImpl->mEndpointLocatorMap.find(locatorId);
if (existing != mImpl->mEndpointLocatorMap.end())
{
- throw LocatorAlreadyRegisteredException(locatorId);
+ mImpl->mEventPublisher.sendAddEndpointLocatorEvent(locatorId, regexList, Event::FAILURE);
+ throw LocatorAlreadyRegisteredException(locatorId);
}
RegisteredLocator newLocator(locator, regexList);
mImpl->mEndpointLocatorMap[locatorId] = newLocator;
+ mImpl->mEventPublisher.sendAddEndpointLocatorEvent(locatorId, regexList, Event::SUCCESS);
}
catch (...)
{
// TBD... Logging!
cout << "Exception adding EndpointLocator." << endl;
+ mImpl->mEventPublisher.sendAddEndpointLocatorEvent(locatorId, regexList, Event::FAILURE);
return;
}
}
@@ -96,9 +107,11 @@ void EndpointRegistry::removeEndpointLocator(const ::std::string& locatorId, con
try
{
mImpl->mEndpointLocatorMap.erase(locatorId);
+ mImpl->mEventPublisher.sendRemoveEndpointLocatorEvent(locatorId, Event::SUCCESS);
}
catch(const std::exception &e)
{
+ mImpl->mEventPublisher.sendRemoveEndpointLocatorEvent(locatorId, Event::FAILURE);
// TBD... Logging!
cout << e.what() << endl;
}
@@ -119,14 +132,18 @@ void EndpointRegistry::setEndpointLocatorDestinationIds(const ::std::string& loc
EndpointLocatorMapIterator existing = mImpl->mEndpointLocatorMap.find(locatorId);
if (existing == mImpl->mEndpointLocatorMap.end())
{
- throw DestinationNotFoundException(locatorId);
+ mImpl->mEventPublisher.sendSetEndpointLocatorDestinationIdsEvent(locatorId, regExList, Event::FAILURE);
+ throw DestinationNotFoundException(locatorId);
}
// Replace the regular expression.
existing->second.setRegEx(regExList);
+ mImpl->mEventPublisher.sendSetEndpointLocatorDestinationIdsEvent(locatorId, regExList, Event::SUCCESS);
+
}
catch(const std::exception &e)
{
+ mImpl->mEventPublisher.sendSetEndpointLocatorDestinationIdsEvent(locatorId, regExList, Event::FAILURE);
// TBD... Logging!
cout << "Exception modifying the destination specifications for EndpointLocator " << locatorId << endl;
cout << " - " << e.what() << endl;
@@ -145,6 +162,7 @@ void EndpointRegistry::setEndpointLocatorDestinationIds(const ::std::string& loc
string modifiedDestination;
if (!mImpl->mScriptProcessor->confirmLookup(destination, modifiedDestination))
{
+ mImpl->mEventPublisher.sendLookupEvent(destination, Event::FAILURE);
// TBD.. logging
cout << "lookup(): denied by confirmLookup() script." << endl;
return endpoints;
@@ -165,6 +183,13 @@ void EndpointRegistry::setEndpointLocatorDestinationIds(const ::std::string& loc
}
}
+ Event::OperationResult result(Event::FAILURE);
+ if (endpoints.size() > 0)
+ {
+ result = Event::SUCCESS;
+ }
+ mImpl->mEventPublisher.sendLookupEvent(destination, result);
+
return endpoints;
}
@@ -183,6 +208,7 @@ void EndpointRegistry::setScriptProcessor(boost::shared_ptr<ScriptProcessor> scr
void EndpointRegistry::clearEndpointLocators()
{
mImpl->mEndpointLocatorMap.clear();
+ mImpl->mEventPublisher.sendClearEndpointLocatorsEvent();
}
/**
@@ -194,6 +220,7 @@ void EndpointRegistry::clearEndpointLocators()
void EndpointRegistry::setPolicy(::std::string policy)
{
mImpl->mScriptProcessor->setPolicy(policy);
+ mImpl->mEventPublisher.sendSetPolicyEvent(policy);
}
}; // end BasicRoutingService
diff --git a/src/RoutingAdmin.cpp b/src/RoutingAdmin.cpp
index 6a02280..0783102 100644
--- a/src/RoutingAdmin.cpp
+++ b/src/RoutingAdmin.cpp
@@ -1,7 +1,7 @@
#include <boost/regex.hpp>
#include "RoutingAdmin.h"
-#include "BasicRoutingServiceApp.h"
+#include "BasicRoutingServiceDataModel.h"
#include "EndpointRegistry.h"
using namespace ::Hydra::Core::Routing::V1;
diff --git a/src/RoutingServiceEventPublisher.cpp b/src/RoutingServiceEventPublisher.cpp
index b5766c9..8b7a059 100644
--- a/src/RoutingServiceEventPublisher.cpp
+++ b/src/RoutingServiceEventPublisher.cpp
@@ -1,7 +1,7 @@
#include <Ice/Ice.h>
#include <IceStorm/IceStorm.h>
-#include "BasicRoutingServiceApp.h"
+#include "BasicRoutingServiceDataModel.h"
#include "RoutingServiceEventPublisher.h"
using namespace ::std;
@@ -93,7 +93,7 @@ RoutingServiceEventPublisher::RoutingServiceEventPublisher()
* Send a message to the service's event topic to report a lookup event.
*/
void RoutingServiceEventPublisher::sendLookupEvent(const ::std::string& destination,
- ::Hydra::Core::Routing::V1::Event::OperationResult result)
+ ::Hydra::Core::Routing::V1::Event::OperationResult result) const
{
if (!mImpl->isInitialized())
{
@@ -109,7 +109,7 @@ void RoutingServiceEventPublisher::sendLookupEvent(const ::std::string& destinat
*/
void RoutingServiceEventPublisher::sendAddEndpointLocatorEvent(const ::std::string& locatorId,
const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
- ::Hydra::Core::Routing::V1::Event::OperationResult result)
+ ::Hydra::Core::Routing::V1::Event::OperationResult result) const
{
if (!mImpl->isInitialized())
{
@@ -123,7 +123,7 @@ void RoutingServiceEventPublisher::sendAddEndpointLocatorEvent(const ::std::stri
* Send a message to the service's event topic to report the removeEndpointLocator event.
*/
void RoutingServiceEventPublisher::sendRemoveEndpointLocatorEvent(const ::std::string& locatorId,
- ::Hydra::Core::Routing::V1::Event::OperationResult result)
+ ::Hydra::Core::Routing::V1::Event::OperationResult result) const
{
if (!mImpl->isInitialized())
{
@@ -138,7 +138,7 @@ void RoutingServiceEventPublisher::sendRemoveEndpointLocatorEvent(const ::std::s
*/
void RoutingServiceEventPublisher::sendSetEndpointLocatorDestinationIdsEvent(const ::std::string& locatorId,
const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
- ::Hydra::Core::Routing::V1::Event::OperationResult result)
+ ::Hydra::Core::Routing::V1::Event::OperationResult result) const
{
if (!mImpl->isInitialized())
{
@@ -151,7 +151,7 @@ void RoutingServiceEventPublisher::sendSetEndpointLocatorDestinationIdsEvent(con
/**
* Send a message to the service's event topic to report the clearEndpointLocators event.
*/
-void RoutingServiceEventPublisher::sendClearEndpointLocatorsEvent()
+void RoutingServiceEventPublisher::sendClearEndpointLocatorsEvent() const
{
if (!mImpl->isInitialized())
{
@@ -164,7 +164,7 @@ void RoutingServiceEventPublisher::sendClearEndpointLocatorsEvent()
/**
* Send a message to the service's event topic to report the setPolicy event.
*/
-void RoutingServiceEventPublisher::sendSetPolicyEvent(const ::std::string& policy)
+void RoutingServiceEventPublisher::sendSetPolicyEvent(const ::std::string& policy) const
{
if (!mImpl->isInitialized())
{
diff --git a/src/RoutingServiceEventPublisher.h b/src/RoutingServiceEventPublisher.h
index d507216..f512d3f 100644
--- a/src/RoutingServiceEventPublisher.h
+++ b/src/RoutingServiceEventPublisher.h
@@ -24,7 +24,7 @@ public:
* @param result Informs event listeners of the operations success or failure.
*/
void sendLookupEvent(const ::std::string& destination,
- ::Hydra::Core::Routing::V1::Event::OperationResult result);
+ ::Hydra::Core::Routing::V1::Event::OperationResult result) const;
/**
* Send a message to the service's event topic to report an addEndpointLocator event.
@@ -34,7 +34,7 @@ public:
*/
void sendAddEndpointLocatorEvent(const ::std::string& locatorId,
const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
- ::Hydra::Core::Routing::V1::Event::OperationResult result);
+ ::Hydra::Core::Routing::V1::Event::OperationResult result) const;
/**
* Send a message to the service's event topic to report a removeEndpointLocator event.
@@ -42,7 +42,7 @@ public:
* @param result Informs event listeners of the operations success or failure.
*/
void sendRemoveEndpointLocatorEvent(const ::std::string& locatorId,
- ::Hydra::Core::Routing::V1::Event::OperationResult result);
+ ::Hydra::Core::Routing::V1::Event::OperationResult result) const;
/**
* Send a message to the service's event topic to report a aetEndpointLocatorDestinationIds event.
@@ -52,18 +52,18 @@ public:
*/
void sendSetEndpointLocatorDestinationIdsEvent(const ::std::string& locatorId,
const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
- ::Hydra::Core::Routing::V1::Event::OperationResult result);
+ ::Hydra::Core::Routing::V1::Event::OperationResult result) const;
/**
* Send a message to the service's event topic to report the clearEndpointLocators event.
*/
- void sendClearEndpointLocatorsEvent();
+ void sendClearEndpointLocatorsEvent() const;
/**
* Send a message to the service's event topic to report the setPolicy event.
*/
- void sendSetPolicyEvent(const ::std::string& policy);
+ void sendSetPolicyEvent(const ::std::string& policy) const;
private:
boost::shared_ptr<RoutingServiceEventPublisherPriv> mImpl; // pimpl idiom applied.
commit acc1a6f6f6518dc4c76645b691d64de0a2ab0cf1
Author: Ken Hunt <ken.hunt at digium.com>
Date: Thu Aug 12 23:03:32 2010 -0500
Completed implementation. (Untested)
diff --git a/slice b/slice
index 5c46b79..2886381 160000
--- a/slice
+++ b/slice
@@ -1 +1 @@
-Subproject commit 5c46b79112a585e54925e1913bfe61f9945fa520
+Subproject commit 2886381a2c693563ed1a8955e32e4105d6da6fc0
diff --git a/src/BasicRoutingService.cpp b/src/BasicRoutingService.cpp
deleted file mode 100644
index c34e19d..0000000
--- a/src/BasicRoutingService.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#include <Ice/Ice.h>
-#include <IceStorm/IceStorm.h>
-
-#include <boost/thread.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include "RoutingIf.h"
-#include "LuaScriptProcessor.h"
-#include "RoutingServiceEventPublisher.h"
-#include "EndpointRegistry.h"
-
-using namespace std;
-using namespace Hydra::BasicRoutingService;
-using namespace Hydra::Core::Routing::V1;
-
-class BasicRoutingServiceApp : public Ice::Application
-{
-public:
- BasicRoutingServiceApp() : mDone(false) {}
-
- // Overrides
- virtual int run(int, char*[]);
- virtual void interruptCallback(int);
-
-private:
- bool mDone;
- std::string mAppName;
- // EndpointRegistry mRegistry;
-};
-
-static BasicRoutingServiceApp app;
-int main(int argc, char* argv[])
-{
- app.callbackOnInterrupt();
- return app.main(argc, argv);
-}
-
-void BasicRoutingServiceApp::interruptCallback(int val)
-{
- cout << "Interrupted..." << endl;
- mDone = true;
- _exit(EXIT_SUCCESS);
-}
-
-/**
- * Overload of the Ice::Application::run method.
- */
-int BasicRoutingServiceApp::run(int argc, char* argv[])
-{
- mAppName = argv[0];
- Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("BasicRoutingServiceAdapter");
-
- EndpointRegistry *registry(new EndpointRegistry());
- boost::shared_ptr<ScriptProcessor> scriptProcesor(new LuaScriptProcessor());
- registry->setScriptProcessor(scriptProcesor);
-
- LocatorRegistryPtr locatorRegistry(registry);
- adapter->add(locatorRegistry, communicator()->stringToIdentity("RoutingService"));
-
- adapter->activate();
-
- communicator()->waitForShutdown();
-
- return EXIT_SUCCESS;
-}
\ No newline at end of file
diff --git a/src/BasicRoutingServiceApp.cpp b/src/BasicRoutingServiceApp.cpp
new file mode 100644
index 0000000..69fc11d
--- /dev/null
+++ b/src/BasicRoutingServiceApp.cpp
@@ -0,0 +1,135 @@
+#include <Ice/Ice.h>
+#include <IceStorm/IceStorm.h>
+
+#include <boost/thread.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "BasicRoutingServiceApp.h"
+#include "RoutingIf.h"
+#include "LuaScriptProcessor.h"
+#include "RoutingServiceEventPublisher.h"
+#include "EndpointRegistry.h"
+#include "RoutingAdmin.h"
+
+using namespace std;
+using namespace Hydra::BasicRoutingService;
+using namespace Hydra::Core::Routing::V1;
+
+namespace Hydra
+{
+namespace BasicRoutingService
+{
+/**
+ * Private implementation of the BasicRoutingServiceDataModel singleton.
+ */
+class BasicRoutingServiceDataModelImpl : public BasicRoutingServiceDataModel
+{
+public:
+ virtual const Ice::CommunicatorPtr getCommunicator()
+ {
+ return mCommunicator;
+ }
+
+ virtual const RoutingServiceEventPublisher& getEventPublisher()
+ {
+ return *mEventPublisher;
+ }
+
+ virtual EndpointRegistry& getEndpointRegistry()
+ {
+ return *mEndpointRegistry;
+ }
+
+ /**
+ * Cleanup the dangling cruft.
+ */
+ void cleanup()
+ {
+ mCommunicator = 0;
+
+ if (mEventPublisher != 0)
+ {
+ delete mEventPublisher;
+ mEventPublisher = 0;
+ }
+ }
+
+ Ice::CommunicatorPtr mCommunicator;
+ RoutingServiceEventPublisher *mEventPublisher;
+ EndpointRegistry *mEndpointRegistry;
+};
+static BasicRoutingServiceDataModelImpl mDataModelInstance;
+
+BasicRoutingServiceDataModel& BasicRoutingServiceDataModel::getInstance()
+{
+ return mDataModelInstance;
+}
+
+/**
+ * This private class defines the service's main entry point.
+ */
+class BasicRoutingServiceApp : public Ice::Application
+{
+public:
+ BasicRoutingServiceApp() : mDone(false) {}
+
+ // Overrides
+ virtual int run(int, char*[]);
+ virtual void interruptCallback(int);
+
+private:
+ bool mDone;
+ std::string mAppName;
+};
+
+void BasicRoutingServiceApp::interruptCallback(int val)
+{
+ cout << "Interrupted..." << endl;
+ mDone = true;
+ _exit(EXIT_SUCCESS);
+}
+
+/**
+ * Overload of the Ice::Application::run method.
+ */
+int BasicRoutingServiceApp::run(int argc, char* argv[])
+{
+ // Init the Data Model singleton.
+ mDataModelInstance.mCommunicator = communicator();
+
+ mDataModelInstance.mEventPublisher = new RoutingServiceEventPublisher();
+
+ // Create the adapter.
+ mAppName = argv[0];
+ Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("BasicRoutingServiceAdapter");
+
+ // Create and configure the EndpointRegistry.
+ mDataModelInstance.mEndpointRegistry = new EndpointRegistry();
+ boost::shared_ptr<ScriptProcessor> scriptProcesor(new LuaScriptProcessor());
+ mDataModelInstance.mEndpointRegistry->setScriptProcessor(scriptProcesor);
+
+ LocatorRegistryPtr locatorRegistry(mDataModelInstance.mEndpointRegistry);
+ adapter->add(locatorRegistry, communicator()->stringToIdentity("RoutingService"));
+
+ // Create and configure the Admin interface
+ RoutingServiceAdminPtr adminInterface = new RoutingAdmin();
+ adapter->add(adminInterface, communicator()->stringToIdentity("RoutingAdmin"));
+
+ adapter->activate();
+
+ communicator()->waitForShutdown();
+
+ mDataModelInstance.cleanup();
+
+ return EXIT_SUCCESS;
+}
+
+}; // end BasicRoutingService
+}; // end Hydra
+
+static BasicRoutingServiceApp app;
+int main(int argc, char* argv[])
+{
+ app.callbackOnInterrupt();
+ return app.main(argc, argv);
+}
\ No newline at end of file
diff --git a/src/BasicRoutingServiceApp.h b/src/BasicRoutingServiceApp.h
new file mode 100644
index 0000000..1be79be
--- /dev/null
+++ b/src/BasicRoutingServiceApp.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <Ice/Ice.h>
+
+namespace Hydra
+{
+namespace BasicRoutingService
+{
+class RoutingServiceEventPublisher;
+class EndpointRegistry;
+
+/**
+ * Singleton for access to the service's data model.
+ */
+class BasicRoutingServiceDataModel
+{
+public:
+ static BasicRoutingServiceDataModel &getInstance();
+
+ virtual const Ice::CommunicatorPtr getCommunicator() = 0;
+ virtual const RoutingServiceEventPublisher& getEventPublisher() = 0;
+ virtual EndpointRegistry& getEndpointRegistry() = 0;
+
+protected:
+ BasicRoutingServiceDataModel() {};
+ ~BasicRoutingServiceDataModel() {};
+};
+
+}; // BasicRoutingService
+}; // Hydra
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ac26c72..4ca784c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,7 +5,8 @@ get_filename_component(LUA_LOC ${LUA_LIBRARIES} PATH)
LINK_DIRECTORIES(${LUA_LOC})
include_directories(${LUA_INCLUDE_DIR})
hydra_component_add_slice(BasicRoutingService RoutingIf)
-hydra_component_add_file(BasicRoutingService BasicRoutingService.cpp)
+hydra_component_add_file(BasicRoutingService BasicRoutingServiceApp.cpp)
+hydra_component_add_file(BasicRoutingService BasicRoutingServiceApp.h)
hydra_component_add_file(BasicRoutingService RoutingAdmin.cpp)
hydra_component_add_file(BasicRoutingService RoutingAdmin.h)
hydra_component_add_file(BasicRoutingService EndpointRegistry.cpp)
diff --git a/src/EndpointRegistry.cpp b/src/EndpointRegistry.cpp
index 69a2dc6..82316a3 100644
--- a/src/EndpointRegistry.cpp
+++ b/src/EndpointRegistry.cpp
@@ -176,5 +176,25 @@ void EndpointRegistry::setScriptProcessor(boost::shared_ptr<ScriptProcessor> scr
mImpl->mScriptProcessor = scriptProcessor;
}
+/**
+ * Drop references to all EndpointLocators that have been registered.
+ * Note: Admin function.
+ */
+void EndpointRegistry::clearEndpointLocators()
+{
+ mImpl->mEndpointLocatorMap.clear();
+}
+
+/**
+ * Sends a policy string to the script processor. The default implementation is a no-op,
+ * but site-specific scripts may make use it.
+ * Note: Admin function.
+ * @param policy A site-specific policy specification.
+ */
+void EndpointRegistry::setPolicy(::std::string policy)
+{
+ mImpl->mScriptProcessor->setPolicy(policy);
+}
+
}; // end BasicRoutingService
}; // end Hydra
\ No newline at end of file
diff --git a/src/EndpointRegistry.h b/src/EndpointRegistry.h
index fd5f93f..4f66dc2 100644
--- a/src/EndpointRegistry.h
+++ b/src/EndpointRegistry.h
@@ -19,18 +19,59 @@ public:
void EndpointRegistry::setScriptProcessor(boost::shared_ptr<ScriptProcessor> scriptProcessor);
- // LocatorRegistry overrides
+public:
+ // LocatorRegistry overrides
+
+ /**
+ * Register an EndpointLocator that can provide endpoints.
+ * @param id A unique identifier for the added EndpointLocator.
+ * @param destinationIdRangeList A set of regular expressions that define the valid endpoint ids
+ * the locator being added supports.
+ */
virtual void addEndpointLocator(const ::std::string& locatorId,
const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
const ::Hydra::Core::Routing::V1::EndpointLocatorPrx& locator,
const ::Ice::Current& = ::Ice::Current());
+
+ /**
+ * Remove an EndpointLocator from the registry. The EndpointLocator must have been previously added
+ * via a call to addEndpointLocator.
+ * @param The unique id of the locator to remove.
+ */
virtual void removeEndpointLocator(const ::std::string& locatorId, const ::Ice::Current& = ::Ice::Current());
+
+
+ /**
+ * Modify the range of ids managed by a previously added EndpointLocator.
+ * @param id A unique identifier for the added EndpointLocator.
+ * @param A list of reqular expressions that define the the valid endpoint ids. This
+ * set of regular expressions completely replaces the current set.
+ */
virtual void setEndpointLocatorDestinationIds(const ::std::string& locatorId,
const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
const ::Ice::Current& = ::Ice::Current());
// EndpointLocator overrides
- virtual ::Hydra::Core::Endpoint::V1::EndpointSeq lookup(const ::std::string& , const ::Ice::Current& = ::Ice::Current());
+
+ /**
+ * Returns the endpoints that match the specified destination id.
+ * @param id String identifier of the the destination.
+ */
+ virtual ::Hydra::Core::Endpoint::V1::EndpointSeq lookup(const ::std::string& destination, const ::Ice::Current& = ::Ice::Current());
+
+public:
+
+ /**
+ * Drop references to all EndpointLocators that have been registered.
+ */
+ void clearEndpointLocators();
+
+ /**
+ * Sends a policy string to the script processor. The default implementation is a no-op,
+ * but site-specific scripts may make use it.
+ * @param policy A site-specific policy specification.
+ */
+ void setPolicy(::std::string policy);
private:
diff --git a/src/RoutingAdmin.cpp b/src/RoutingAdmin.cpp
index e69de29..6a02280 100644
--- a/src/RoutingAdmin.cpp
+++ b/src/RoutingAdmin.cpp
@@ -0,0 +1,42 @@
+#include <boost/regex.hpp>
+
+#include "RoutingAdmin.h"
+#include "BasicRoutingServiceApp.h"
+#include "EndpointRegistry.h"
+
+using namespace ::Hydra::Core::Routing::V1;
+using namespace ::std;
+
+namespace Hydra
+{
+namespace BasicRoutingService
+{
+
+RoutingAdmin::RoutingAdmin()
+{
+}
+
+/**
+ * Drop references to all EndpointLocators that have been registered.
+ */
+void RoutingAdmin::clearEndpointLocators(const ::Ice::Current&)
+{
+ // For now we just forward to the registry. Some type of authentication may be required
+ // in the future, or perhaps the access to the interface is controlled externally.
+ BasicRoutingServiceDataModel::getInstance().getEndpointRegistry().clearEndpointLocators();
+}
+
+/**
+ * Sends a policy string to the script processor. The default implementation is a no-op,
+ * but site-specific scripts may make use it.
+ * @param policy A site-specific policy specification.
+ */
+void RoutingAdmin::setPolicy(const ::std::string& policy, const ::Ice::Current&)
+{
+ // For now we just forward to the registry. Some type of authentication may be required
+ // in the future, or perhaps the access to the interface is controlled externally.
+ BasicRoutingServiceDataModel::getInstance().getEndpointRegistry().setPolicy(policy);
+}
+
+}; // end BasicRoutingService
+}; // end Hydra
\ No newline at end of file
diff --git a/src/RoutingAdmin.h b/src/RoutingAdmin.h
index e69de29..b7f6fb0 100644
--- a/src/RoutingAdmin.h
+++ b/src/RoutingAdmin.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include "RoutingIf.h"
+
+namespace Hydra
+{
+namespace BasicRoutingService
+{
+class EndpointRegistryPriv;
+
+/**
+ * This class exists to provide separation between the EndpointRegistry and the administrative functions.
+ */
+class RoutingAdmin : public Hydra::Core::Routing::V1::RoutingServiceAdmin
+{
+public:
+ RoutingAdmin();
+
+public: // RoutingServiceAdmin overrides
+
+ /**
+ * Drop references to all EndpointLocators that have been registered.
+ */
+ virtual void clearEndpointLocators(const ::Ice::Current& = ::Ice::Current());
+
+ /**
+ * Sends a policy string to the script processor. The default implementation is a no-op,
+ * but site-specific scripts may make use it.
+ * @param policy A site-specific policy specification.
+ */
+ virtual void setPolicy(const ::std::string& policy, const ::Ice::Current& = ::Ice::Current());
+
+};
+
+}; // end BasicRoutingService
+}; // end Hydra
\ No newline at end of file
diff --git a/src/RoutingServiceEventPublisher.cpp b/src/RoutingServiceEventPublisher.cpp
index 7888f1c..b5766c9 100644
--- a/src/RoutingServiceEventPublisher.cpp
+++ b/src/RoutingServiceEventPublisher.cpp
@@ -1,6 +1,7 @@
#include <Ice/Ice.h>
#include <IceStorm/IceStorm.h>
+#include "BasicRoutingServiceApp.h"
#include "RoutingServiceEventPublisher.h"
using namespace ::std;
@@ -11,42 +12,41 @@ namespace Hydra
namespace BasicRoutingService
{
+/**
+ * The private implementation of RoutingServiceEventPublisher.
+ */
class RoutingServiceEventPublisherPriv
{
public:
- RoutingServiceEventPublisherPriv(const Ice::CommunicatorPtr& communicator) : mCommunicator(communicator), mInitialized(false)
+ RoutingServiceEventPublisherPriv() : mInitialized(false)
{
+ initialize();
}
- const Ice::CommunicatorPtr& mCommunicator;
- Event::RoutingEventsPrx mEventTopic;
- bool mInitialized;
-};
-
-RoutingServiceEventPublisher::RoutingServiceEventPublisher(const Ice::CommunicatorPtr& communicator)
- : mImpl(new RoutingServiceEventPublisherPriv(communicator))
-{
-}
+ /**
+ * Initialization. Primarily involves acquring access to specific IceStorm topic.
+ */
+ void initialize()
+ {
+ const Ice::CommunicatorPtr& communicator = BasicRoutingServiceDataModel::getInstance().getCommunicator();
-void RoutingServiceEventPublisher::initialize()
-{
- IceStorm::TopicManagerPrx topicManager =
- IceStorm::TopicManagerPrx::checkedCast(mImpl->mCommunicator->propertyToProxy("TopicManager.Proxy"));
+ IceStorm::TopicManagerPrx topicManager =
+ IceStorm::TopicManagerPrx::checkedCast(communicator->propertyToProxy("TopicManager.Proxy"));
- if(!topicManager)
- {
+ if(!topicManager)
+ {
cerr << "Invalid proxy to IceStorm. Missing config for TopicManager.Proxy?" << endl;
- }
+ }
- cout << "RoutingServiceEventPublisher::initialize(): Got IceStorm proxy: TopicManager.Proxy" << endl;
+ cout << "RoutingServiceEventPublisher::initialize(): Got IceStorm proxy: TopicManager.Proxy" << endl;
- IceStorm::TopicPrx topic;
- try
- {
+ IceStorm::TopicPrx topic;
+ try
+ {
topic = topicManager->retrieve(Event::TopicId);
- }
- catch(const IceStorm::NoSuchTopic&)
- {
+ }
+ catch(const IceStorm::NoSuchTopic&)
+ {
try
{
topic = topicManager->create(Event::TopicId);
@@ -55,44 +55,124 @@ void RoutingServiceEventPublisher::initialize()
{
cerr << "Possible race condition creating IceStorm topic " << Event::TopicId << ". Suggest Restart!" << endl;
}
- }
+ }
- Ice::ObjectPrx publisher = topic->getPublisher();
- mImpl->mEventTopic = Event::RoutingEventsPrx::uncheckedCast(publisher);
-
- mImpl->mInitialized = true;
-}
+ Ice::ObjectPrx publisher = topic->getPublisher();
+ mEventTopic = Event::RoutingEventsPrx::uncheckedCast(publisher);
+
+ mInitialized = true;
+ }
-void RoutingServiceEventPublisher::lookupEvent(const ::std::string&,
- ::Hydra::Core::Routing::V1::Event::OperationResult)
+ /**
+ * Utiltity to check for initialization state.
+ */
+ bool isInitialized()
+ {
+ if (!mInitialized)
+ {
+ cout << "Attempting to use RoutingServiceEventPublisher in uninitialized state! IceStorm may be inaccessible." << endl;
+ }
+
+ return mInitialized;
+ }
+
+public:
+ Event::RoutingEventsPrx mEventTopic;
+ bool mInitialized;
+};
+
+/**
+ * Class constructor.
+ */
+RoutingServiceEventPublisher::RoutingServiceEventPublisher()
+ : mImpl(new RoutingServiceEventPublisherPriv())
{
}
-void RoutingServiceEventPublisher::addEndpointLocatorEvent(const ::std::string&,
- const ::Hydra::Core::Routing::V1::RegExSeq&,
- ::Hydra::Core::Routing::V1::Event::OperationResult)
+/**
+ * Send a message to the service's event topic to report a lookup event.
+ */
+void RoutingServiceEventPublisher::sendLookupEvent(const ::std::string& destination,
+ ::Hydra::Core::Routing::V1::Event::OperationResult result)
{
+ if (!mImpl->isInitialized())
+ {
+ return;
+ }
+
+ mImpl->mEventTopic->lookupEvent(destination, result);
}
-void RoutingServiceEventPublisher::removeEndpointLocatorEvent(const ::std::string&,
- ::Hydra::Core::Routing::V1::Event::OperationResult)
+
+/**
+ * Send a message to the service's event topic to report the addEndpointLocator event.
+ */
+void RoutingServiceEventPublisher::sendAddEndpointLocatorEvent(const ::std::string& locatorId,
+ const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
+ ::Hydra::Core::Routing::V1::Event::OperationResult result)
{
+ if (!mImpl->isInitialized())
+ {
+ return;
+ }
+
+ mImpl->mEventTopic->addEndpointLocatorEvent(locatorId, regexList, result);
}
-void RoutingServiceEventPublisher::setEndpointLocatorDestinationIdsEvent(const ::std::string&,
- const ::Hydra::Core::Routing::V1::RegExSeq&,
- ::Hydra::Core::Routing::V1::Event::OperationResult)
+/**
+ * Send a message to the service's event topic to report the removeEndpointLocator event.
+ */
+void RoutingServiceEventPublisher::sendRemoveEndpointLocatorEvent(const ::std::string& locatorId,
+ ::Hydra::Core::Routing::V1::Event::OperationResult result)
{
+ if (!mImpl->isInitialized())
+ {
+ return;
+ }
+
+ mImpl->mEventTopic->removeEndpointLocatorEvent(locatorId, result);
}
-void RoutingServiceEventPublisher::clearEndpointLocatorsEvent()
+/**
+ * Send a message to the service's event topic to report the setEndpointLocatorDestinationIds event.
+ */
+void RoutingServiceEventPublisher::sendSetEndpointLocatorDestinationIdsEvent(const ::std::string& locatorId,
+ const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
+ ::Hydra::Core::Routing::V1::Event::OperationResult result)
{
+ if (!mImpl->isInitialized())
+ {
+ return;
+ }
+
+ mImpl->mEventTopic->setEndpointLocatorDestinationIdsEvent(locatorId, regexList, result);
}
-void RoutingServiceEventPublisher::setPolicyEvent(const ::std::string& policy)
+/**
+ * Send a message to the service's event topic to report the clearEndpointLocators event.
+ */
+void RoutingServiceEventPublisher::sendClearEndpointLocatorsEvent()
{
+ if (!mImpl->isInitialized())
+ {
+ return;
+ }
+
+ mImpl->mEventTopic->clearEndpointLocatorsEvent();
}
+/**
+ * Send a message to the service's event topic to report the setPolicy event.
+ */
+void RoutingServiceEventPublisher::sendSetPolicyEvent(const ::std::string& policy)
+{
+ if (!mImpl->isInitialized())
+ {
+ return;
+ }
+
+ mImpl->mEventTopic->setPolicyEvent(policy);
+}
}; // end BasicRoutingService
}; // end Hydra
\ No newline at end of file
diff --git a/src/RoutingServiceEventPublisher.h b/src/RoutingServiceEventPublisher.h
index 55921a6..d507216 100644
--- a/src/RoutingServiceEventPublisher.h
+++ b/src/RoutingServiceEventPublisher.h
@@ -11,30 +11,62 @@ namespace BasicRoutingService
class RoutingServiceEventPublisherPriv;
/**
- *
+ * Publishes key events to the rest of the system.
*/
class RoutingServiceEventPublisher
{
public:
- RoutingServiceEventPublisher(const Ice::CommunicatorPtr&);
-
- // RoutingEvents Overrides
- virtual void lookupEvent(const ::std::string&,
- ::Hydra::Core::Routing::V1::Event::OperationResult);
- virtual void addEndpointLocatorEvent(const ::std::string&,
- const ::Hydra::Core::Routing::V1::RegExSeq&,
- ::Hydra::Core::Routing::V1::Event::OperationResult);
- virtual void removeEndpointLocatorEvent(const ::std::string&,
- ::Hydra::Core::Routing::V1::Event::OperationResult);
- virtual void setEndpointLocatorDestinationIdsEvent(const ::std::string&,
- const ::Hydra::Core::Routing::V1::RegExSeq&,
- ::Hydra::Core::Routing::V1::Event::OperationResult);
- virtual void clearEndpointLocatorsEvent();
- virtual void setPolicyEvent(const ::std::string&);
+ RoutingServiceEventPublisher();
+
+ /**
+ * Send a message to the service's event topic to report a lookup event.
+ * @param destination The destination to be looked up.
+ * @param result Informs event listeners of the operations success or failure.
+ */
+ void sendLookupEvent(const ::std::string& destination,
+ ::Hydra::Core::Routing::V1::Event::OperationResult result);
+
+ /**
+ * Send a message to the service's event topic to report an addEndpointLocator event.
+ * @param locatorId The identity of the EndpointLocator being added.
+ * @param regexList List of regex strings used to identify the destinations available by this locator.
+ * @param result Informs event listeners of the operations success or failure.
+ */
+ void sendAddEndpointLocatorEvent(const ::std::string& locatorId,
+ const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
+ ::Hydra::Core::Routing::V1::Event::OperationResult result);
+
+ /**
+ * Send a message to the service's event topic to report a removeEndpointLocator event.
+ * @param locatorId The identity of the EndpointLocator being removed.
+ * @param result Informs event listeners of the operations success or failure.
+ */
+ void sendRemoveEndpointLocatorEvent(const ::std::string& locatorId,
+ ::Hydra::Core::Routing::V1::Event::OperationResult result);
+
+ /**
+ * Send a message to the service's event topic to report a aetEndpointLocatorDestinationIds event.
+ * @param locatorId The identity of the EndpointLocator whose destination specifications should be changed.
+ * @param regexList New list of regex strings to be used to identify the destinations available by this locator.
+ * @param result Informs event listeners of the operations success or failure.
+ */
+ void sendSetEndpointLocatorDestinationIdsEvent(const ::std::string& locatorId,
+ const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
+ ::Hydra::Core::Routing::V1::Event::OperationResult result);
+
+
+ /**
+ * Send a message to the service's event topic to report the clearEndpointLocators event.
+ */
+ void sendClearEndpointLocatorsEvent();
+
+ /**
+ * Send a message to the service's event topic to report the setPolicy event.
+ */
+ void sendSetPolicyEvent(const ::std::string& policy);
private:
- void initialize();
- boost::shared_ptr<RoutingServiceEventPublisherPriv> mImpl;
+ boost::shared_ptr<RoutingServiceEventPublisherPriv> mImpl; // pimpl idiom applied.
};
}; // end BasicRoutingService
commit 43fe873e3297d30d60d5a025bcd6f1180934ff7e
Author: Ken Hunt <ken.hunt at digium.com>
Date: Wed Aug 11 20:28:51 2010 -0500
Roughed out implementation.
diff --git a/src/BasicRoutingService.cpp b/src/BasicRoutingService.cpp
index a708dd7..c34e19d 100644
--- a/src/BasicRoutingService.cpp
+++ b/src/BasicRoutingService.cpp
@@ -1,6 +1,65 @@
#include <Ice/Ice.h>
-#include <IceBox/IceBox.h>
#include <IceStorm/IceStorm.h>
-#include "RoutingI.h"
+#include <boost/thread.hpp>
+#include <boost/shared_ptr.hpp>
+#include "RoutingIf.h"
+#include "LuaScriptProcessor.h"
+#include "RoutingServiceEventPublisher.h"
+#include "EndpointRegistry.h"
+
+using namespace std;
+using namespace Hydra::BasicRoutingService;
+using namespace Hydra::Core::Routing::V1;
+
+class BasicRoutingServiceApp : public Ice::Application
+{
+public:
+ BasicRoutingServiceApp() : mDone(false) {}
+
+ // Overrides
+ virtual int run(int, char*[]);
+ virtual void interruptCallback(int);
+
+private:
+ bool mDone;
+ std::string mAppName;
+ // EndpointRegistry mRegistry;
+};
+
+static BasicRoutingServiceApp app;
+int main(int argc, char* argv[])
+{
+ app.callbackOnInterrupt();
+ return app.main(argc, argv);
+}
+
+void BasicRoutingServiceApp::interruptCallback(int val)
+{
+ cout << "Interrupted..." << endl;
+ mDone = true;
+ _exit(EXIT_SUCCESS);
+}
+
+/**
+ * Overload of the Ice::Application::run method.
+ */
+int BasicRoutingServiceApp::run(int argc, char* argv[])
+{
+ mAppName = argv[0];
+ Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("BasicRoutingServiceAdapter");
+
+ EndpointRegistry *registry(new EndpointRegistry());
+ boost::shared_ptr<ScriptProcessor> scriptProcesor(new LuaScriptProcessor());
+ registry->setScriptProcessor(scriptProcesor);
+
+ LocatorRegistryPtr locatorRegistry(registry);
+ adapter->add(locatorRegistry, communicator()->stringToIdentity("RoutingService"));
+
+ adapter->activate();
+
+ communicator()->waitForShutdown();
+
+ return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c5e5dee..ac26c72 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,8 +1,25 @@
# Create the actual standalone basic routing component
hydra_component_init(BasicRoutingService CXX)
-hydra_component_add_slice(BasicRoutingService RoutingI)
+INCLUDE(FindLua51)
+get_filename_component(LUA_LOC ${LUA_LIBRARIES} PATH)
+LINK_DIRECTORIES(${LUA_LOC})
+include_directories(${LUA_INCLUDE_DIR})
+hydra_component_add_slice(BasicRoutingService RoutingIf)
hydra_component_add_file(BasicRoutingService BasicRoutingService.cpp)
+hydra_component_add_file(BasicRoutingService RoutingAdmin.cpp)
+hydra_component_add_file(BasicRoutingService RoutingAdmin.h)
+hydra_component_add_file(BasicRoutingService EndpointRegistry.cpp)
+hydra_component_add_file(BasicRoutingService EndpointRegistry.h)
+hydra_component_add_file(BasicRoutingService ScriptProcessor.h)
+hydra_component_add_file(BasicRoutingService LuaScriptProcessor.cpp)
+hydra_component_add_file(BasicRoutingService LuaScriptProcessor.h)
+hydra_component_add_file(BasicRoutingService RoutingServiceEventPublisher.cpp)
+hydra_component_add_file(BasicRoutingService RoutingServiceEventPublisher.h)
+
hydra_component_add_ice_libraries(BasicRoutingService IceStorm)
-hydra_component_add_boost_libraries(BasicRoutingService core thread)
+hydra_component_add_boost_libraries(BasicRoutingService thread core regex)
+
hydra_component_build_standalone(BasicRoutingService)
+target_link_libraries(BasicRoutingService ${LUA_LIBRARIES})
+
hydra_component_install(BasicRoutingService RUNTIME bin "Basic Routing Service" Core)
diff --git a/src/EndpointRegistry.cpp b/src/EndpointRegistry.cpp
new file mode 100644
index 0000000..69a2dc6
--- /dev/null
+++ b/src/EndpointRegistry.cpp
@@ -0,0 +1,180 @@
+#include <boost/regex.hpp>
+
+#include "EndpointRegistry.h"
+#include "ScriptProcessor.h"
+
+using namespace ::Hydra::Core::Routing::V1;
+using namespace ::std;
+
+namespace Hydra
+{
+namespace BasicRoutingService
+{
+
+struct RegisteredLocator
+{
+public:
+ RegisteredLocator() {};
+ RegisteredLocator(EndpointLocatorPrx l, const RegExSeq &inputStringList) : locator(l)
+ {
+ setRegEx(inputStringList);
+ }
+
+ void setRegEx(const RegExSeq &inputStringList)
+ {
+ regexList.clear();
+
+ // Store the string representations as regular expressions.
+ vector<string>::const_iterator s;
+ for(s=inputStringList.begin(); s != inputStringList.end(); s++)
+ {
+ boost::regex reg;
+ reg.assign(*s);
+ regexList.push_back(reg);
+ }
+ }
+
+ EndpointLocatorPrx locator;
+ vector<boost::regex> regexList;
+};
+
+/**
+ * Provides the private implementation of the EndpointRegistry.
+ */
+class EndpointRegistryPriv
+{
+public:
+ map<std::string, RegisteredLocator> mEndpointLocatorMap;
+ boost::shared_ptr<ScriptProcessor> mScriptProcessor;
+};
+typedef map<std::string, RegisteredLocator>::iterator EndpointLocatorMapIterator;
+
+/**
+ * Constructor.
+ */
+EndpointRegistry::EndpointRegistry() : mImpl(new EndpointRegistryPriv())
+{
+}
+
+/**
+ * Register an EndpointLocator that can provide endpoints.
+ * @param id A unique identifier for the added EndpointLocator.
+ * @param destinationIdRangeList A set of regular expressions that define the valid endpoint ids
+ * the locator being added supports.
+ */
+void EndpointRegistry::addEndpointLocator(const ::std::string& locatorId,
+ const RegExSeq& regexList,
+ const EndpointLocatorPrx& locator,
+ const ::Ice::Current&)
+{
+ try
+ {
+ EndpointLocatorMapIterator existing = mImpl->mEndpointLocatorMap.find(locatorId);
+ if (existing != mImpl->mEndpointLocatorMap.end())
+ {
+ throw LocatorAlreadyRegisteredException(locatorId);
+ }
+
+ RegisteredLocator newLocator(locator, regexList);
+
+ mImpl->mEndpointLocatorMap[locatorId] = newLocator;
+ }
+ catch (...)
+ {
+ // TBD... Logging!
+ cout << "Exception adding EndpointLocator." << endl;
+ return;
+ }
+}
+
+/**
+ * Remove an EndpointLocator.
+ * @param The unique id of the locator to remove.
+ */
+void EndpointRegistry::removeEndpointLocator(const ::std::string& locatorId, const ::Ice::Current&)
+{
+ try
+ {
+ mImpl->mEndpointLocatorMap.erase(locatorId);
+ }
+ catch(const std::exception &e)
+ {
+ // TBD... Logging!
+ cout << e.what() << endl;
+ }
+}
+
+/**
+ * Modify the range of device ids managed by a previously added EndpointLocator.
+ * @param id A unique identifier for the added EndpointLocator.
+ * @param A list of reqular expressions that define the the valid endpoint ids. This
+ * set of regular expressions completely replaces the current set.
+ */
+void EndpointRegistry::setEndpointLocatorDestinationIds(const ::std::string& locatorId,
+ const ::Hydra::Core::Routing::V1::RegExSeq& regExList,
+ const ::Ice::Current&)
+{
+ try
+ {
+ EndpointLocatorMapIterator existing = mImpl->mEndpointLocatorMap.find(locatorId);
+ if (existing == mImpl->mEndpointLocatorMap.end())
+ {
+ throw DestinationNotFoundException(locatorId);
+ }
+
+ // Replace the regular expression.
+ existing->second.setRegEx(regExList);
+ }
+ catch(const std::exception &e)
+ {
+ // TBD... Logging!
+ cout << "Exception modifying the destination specifications for EndpointLocator " << locatorId << endl;
+ cout << " - " << e.what() << endl;
+ }
+
+}
+
+/**
+ * Returns the endpoints that match the specified destination id.
+ * @param id String identifier of the the destination.
+ */
+::Hydra::Core::Endpoint::V1::EndpointSeq EndpointRegistry::lookup(const ::std::string& destination, const ::Ice::Current&)
+{
+ ::Hydra::Core::Endpoint::V1::EndpointSeq endpoints;
+
+ string modifiedDestination;
+ if (!mImpl->mScriptProcessor->confirmLookup(destination, modifiedDestination))
+ {
+ // TBD.. logging
+ cout << "lookup(): denied by confirmLookup() script." << endl;
+ return endpoints;
+ }
+
+ EndpointLocatorMapIterator entry;
+ for(entry = mImpl->mEndpointLocatorMap.begin(); entry != mImpl->mEndpointLocatorMap.end(); entry++)
+ {
+ // Test to see if the destination matches any of this entry's regular expressions.
+ vector<boost::regex>::iterator reg;
+ for(reg=entry->second.regexList.begin(); reg != entry->second.regexList.end(); reg++)
+ {
+ if (boost::regex_match(destination, *reg))
+ {
+ endpoints = entry->second.locator->lookup(destination);
+ break;
+ }
+ }
+ }
+
+ return endpoints;
+}
+
+/**
+ * Configure this object with a ScriptProcessor.
+ */
+void EndpointRegistry::setScriptProcessor(boost::shared_ptr<ScriptProcessor> scriptProcessor)
+{
+ mImpl->mScriptProcessor = scriptProcessor;
+}
+
+}; // end BasicRoutingService
+}; // end Hydra
\ No newline at end of file
diff --git a/src/EndpointRegistry.h b/src/EndpointRegistry.h
new file mode 100644
index 0000000..fd5f93f
--- /dev/null
+++ b/src/EndpointRegistry.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include "RoutingIf.h"
+
+namespace Hydra
+{
+namespace BasicRoutingService
+{
+
+class EndpointRegistryPriv;
+class ScriptProcessor;
+
+class EndpointRegistry : public Hydra::Core::Routing::V1::LocatorRegistry
+{
+public:
+ EndpointRegistry();
+
+ void EndpointRegistry::setScriptProcessor(boost::shared_ptr<ScriptProcessor> scriptProcessor);
+
+ // LocatorRegistry overrides
+ virtual void addEndpointLocator(const ::std::string& locatorId,
+ const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
+ const ::Hydra::Core::Routing::V1::EndpointLocatorPrx& locator,
+ const ::Ice::Current& = ::Ice::Current());
+ virtual void removeEndpointLocator(const ::std::string& locatorId, const ::Ice::Current& = ::Ice::Current());
+ virtual void setEndpointLocatorDestinationIds(const ::std::string& locatorId,
+ const ::Hydra::Core::Routing::V1::RegExSeq& regexList,
+ const ::Ice::Current& = ::Ice::Current());
+
+ // EndpointLocator overrides
+ virtual ::Hydra::Core::Endpoint::V1::EndpointSeq lookup(const ::std::string& , const ::Ice::Current& = ::Ice::Current());
+
+
+private:
+ boost::shared_ptr<EndpointRegistryPriv> mImpl;
+};
+
+}; // end BasicRoutingService
+}; // end Hydra
\ No newline at end of file
diff --git a/src/LuaScriptProcessor.cpp b/src/LuaScriptProcessor.cpp
new file mode 100644
index 0000000..c920f3d
--- /dev/null
+++ b/src/LuaScriptProcessor.cpp
@@ -0,0 +1,185 @@
+#include "lua.hpp"
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include "LuaScriptProcessor.h"
+
+using namespace ::Hydra::Core::Endpoint::V1;
+using namespace ::std;
+
+namespace Hydra
+{
+namespace BasicRoutingService
+{
+
+struct RawEndpointId
+{
+public:
+ string endpointId;
+ string managerId;
+};
+
+typedef std::vector<RawEndpointId> RawEndpointVector;
+
+/**
+ * Provides the private implementation of the LuaScriptProcessor.
+ */
+class LuaScriptProcessorPriv
+{
+public:
+ LuaScriptProcessorPriv()
+ {
+ }
+
+ ~LuaScriptProcessorPriv()
+ {
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
+
+ lua_close(mLuaState);
+ }
+
+ void initialize()
+ {
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
+
+ mLuaState = lua_open();
+ luaL_openlibs(mLuaState);
+
+ // Load script
+ if (luaL_dofile(mLuaState, "routing.lua"))
+ {
+ cout << lua_tostring(mLuaState, -1) << std::endl;
+ return ;
+ }
+ }
+
+ void setPolicy(const string& policy)
+ {
+ mCurrentPolicy = policy;
+
+ // Call the lua script.
+ // Set function name.
+ lua_getglobal(mLuaState, "setPolicy");
+
+ // Push input arg
+ lua_pushstring(mLuaState, policy.c_str());
+
+ // Call function. One arg, no return results...
+ lua_call(mLuaState, 1, 0);
+ }
+
+ RawEndpointVector lookup(const string& destination)
+ {
+ RawEndpointVector endpoints;
+
+ try
+ {
+ // Call the lua script.
+ // Set function name.
+ lua_getglobal(mLuaState, "lookup");
+
+ // Push input arg
+ lua_pushstring(mLuaState, destination.c_str());
+
+ // Call function. One arg, multiple results...
+ lua_call(mLuaState, 1, LUA_MULTRET);
+
+ int numEndpoints = (int)lua_tonumber(mLuaState, -1);
+ lua_pop(mLuaState, 1);
+
+ if (numEndpoints == 0)
+ {
+ return endpoints;
+ }
+
+ for (int i=0; i < numEndpoints; i++)
+ {
+ RawEndpointId rawEndpoint;
+
+ rawEndpoint.endpointId =lua_tostring(mLuaState, -1);
+ lua_pop(mLuaState, 1);
+
+ rawEndpoint.managerId = lua_tostring(mLuaState, -1);
+ lua_pop(mLuaState, 1);
+
+ endpoints.push_back(rawEndpoint);
+ }
+ }
+ catch (...)
+ {
+ // TBD... Most likely a script error of some type.
+ cout << "Lua Script error in call to lookup()." << endl;
+ }
+ }
+
+ bool confirmLookup(const string& destination, string &modifiedDestination)
+ {
+ try
+ {
+ // Call the lua script.
+ // Set function name.
+ lua_getglobal(mLuaState, "confirmLookup");
+
+ // Push input arg
+ lua_pushstring(mLuaState, destination.c_str());
+
+ // Call function. One arg, 2 results...
+ lua_call(mLuaState, 1, 1);
+
+ int allow = (int)lua_toboolean(mLuaState, -1);
+ lua_pop(mLuaState, 1);
+
+ if (allow == 0)
+ {
+ return false;
+ }
+
+ modifiedDestination = lua_tostring(mLuaState, -1);
+ lua_pop(mLuaState, 1);
+ }
+ catch (...)
+ {
+ // TBD... Most likely a script error of some type.
+ cout << "Lua Script error in call to confirmLookup()." << endl;
... 801 lines suppressed ...
--
asterisk-scf/integration/routing.git
More information about the asterisk-scf-commits
mailing list