{
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
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;
* @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;
};
/**
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);
}