Dispatch remoted messages through SP interface to support non-plugin extensions.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Sun, 19 Sep 2010 01:47:48 +0000 (01:47 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Sun, 19 Sep 2010 01:47:48 +0000 (01:47 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/branches/REL_2@3324 cb58f699-b61c-0410-a6fe-9272a202ed29

shibsp/ServiceProvider.cpp
shibsp/ServiceProvider.h
shibsp/remoting/impl/ListenerService.cpp

index 0e5b3da..30e4423 100644 (file)
@@ -174,10 +174,41 @@ SecurityPolicyProvider* ServiceProvider::getSecurityPolicyProvider(bool required
 {
     if (required)
         throw ConfigurationException("No SecurityPolicyProvider available.");
-    return NULL;
+    return nullptr;
 }
 #endif
 
+Remoted* ServiceProvider::regListener(const char* address, Remoted* listener)
+{
+    Remoted* ret=nullptr;
+    map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
+    if (i!=m_listenerMap.end())
+        ret=i->second;
+    m_listenerMap[address]=listener;
+    Category::getInstance(SHIBSP_LOGCAT".ServiceProvider").info("registered remoted message endpoint (%s)",address);
+    return ret;
+}
+
+bool ServiceProvider::unregListener(const char* address, Remoted* current, Remoted* restore)
+{
+    map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
+    if (i!=m_listenerMap.end() && i->second==current) {
+        if (restore)
+            m_listenerMap[address]=restore;
+        else
+            m_listenerMap.erase(address);
+        Category::getInstance(SHIBSP_LOGCAT".ServiceProvider").info("unregistered remoted message endpoint (%s)",address);
+        return true;
+    }
+    return false;
+}
+
+Remoted* ServiceProvider::lookupListener(const char *address) const
+{
+    map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
+    return (i==m_listenerMap.end()) ? nullptr : i->second;
+}
+
 pair<bool,long> ServiceProvider::doAuthentication(SPRequest& request, bool handler) const
 {
 #ifdef _DEBUG
index 59f75a4..f3003c4 100644 (file)
@@ -43,6 +43,7 @@ namespace shibsp {
     class SHIBSP_API Application;
     class SHIBSP_API Handler;
     class SHIBSP_API ListenerService;
+    class SHIBSP_API Remoted;
     class SHIBSP_API RequestMapper;
     class SHIBSP_API SessionCache;
     class SHIBSP_API SPRequest;
@@ -205,6 +206,36 @@ namespace shibsp {
          * @return a pair containing a "request completed" indicator and a server-specific response code
          */
         virtual std::pair<bool,long> doHandler(SPRequest& request) const;
+
+        /**
+         * Register for a message. Returns existing remote service, allowing message hooking.
+         *
+         * @param address   message address to register
+         * @param svc       pointer to remote service
+         * @return  previous service registered for message, if any
+         */
+        virtual Remoted* regListener(const char* address, Remoted* svc);
+
+        /**
+         * Unregisters service from an address, possibly restoring an original.
+         *
+         * @param address   message address to modify
+         * @param current   pointer to unregistering service
+         * @param restore   service to "restore" registration for
+         * @return  true iff the current service was still registered
+         */
+        virtual bool unregListener(const char* address, Remoted* current, Remoted* restore=nullptr);
+
+        /**
+         * Returns current service registered at an address, if any.
+         *
+         * @param address message address to access
+         * @return  registered service, or nullptr
+         */
+        virtual Remoted* lookupListener(const char* address) const;
+
+    private:
+        std::map<std::string,Remoted*> m_listenerMap;
     };
 
     /**
index f0df7a4..2b1cd62 100644 (file)
@@ -105,10 +105,15 @@ void ListenerService::receive(DDF &in, ostream& out)
         out << outmsg;
     }
 
-    Locker locker(SPConfig::getConfig().getServiceProvider());
-    Remoted* dest=lookup(in.name());
-    if (!dest)
-        throw ListenerException("No destination registered for incoming message addressed to ($1).",params(1,in.name()));
+    // Two stage lookup, on the listener itself, and the SP interface.
+    ServiceProvider* sp = SPConfig::getConfig().getServiceProvider();
+    Locker locker(sp);
+    Remoted* dest = lookup(in.name());
+    if (!dest) {
+        dest = sp->lookupListener(in.name());
+        if (!dest)
+            throw ListenerException("No destination registered for incoming message addressed to ($1).", params(1,in.name()));
+    }
 
     dest->receive(in, out);
 }