[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