00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __PION_SERVICEMANAGER_HEADER__
00021 #define __PION_SERVICEMANAGER_HEADER__
00022
00023 #include <list>
00024 #include <string>
00025 #include <boost/thread/mutex.hpp>
00026 #include <pion/PionConfig.hpp>
00027 #include <pion/PionException.hpp>
00028 #include <pion/PionScheduler.hpp>
00029 #include <pion/PluginManager.hpp>
00030 #include <pion/net/HTTPServer.hpp>
00031 #include <pion/net/WebService.hpp>
00032 #include <pion/platform/ConfigManager.hpp>
00033 #include "PlatformService.hpp"
00034 #include <pion/platform/PluginConfig.hpp>
00035
00036
00037 namespace pion {
00038 namespace server {
00039
00040
00041
00042 class PlatformConfig;
00043
00044
00048 class PION_SERVER_API ServiceManager :
00049 public pion::platform::PluginConfig<PlatformService>
00050 {
00051 public:
00052
00054 class EmptyServerIdException : public PionException {
00055 public:
00056 EmptyServerIdException(const std::string& config_file)
00057 : PionException("Service configuration file includes a Server without a unique identifier: ", config_file) {}
00058 };
00059
00061 class EmptyServiceIdException : public PionException {
00062 public:
00063 EmptyServiceIdException(const std::string& server_id)
00064 : PionException("Server configuration includes a Service without a unique identifier: ", server_id) {}
00065 };
00066
00068 class EmptyServicePluginTypeException : public PionException {
00069 public:
00070 EmptyServicePluginTypeException(const std::string& service_id)
00071 : PionException("Service configuration does not define a plug-in type: ", service_id) {}
00072 };
00073
00075 class EmptyServiceResourceException : public PionException {
00076 public:
00077 EmptyServiceResourceException(const std::string& service_id)
00078 : PionException("Service configuration does not define a resource: ", service_id) {}
00079 };
00080
00082 class EmptyServiceServerIdException : public PionException {
00083 public:
00084 EmptyServiceServerIdException(const std::string& config_file)
00085 : PionException("Service configuration file includes a Service without a Server identifier: ", config_file) {}
00086 };
00087
00089 class EmptyOptionNameException : public PionException {
00090 public:
00091 EmptyOptionNameException(const std::string& service_id)
00092 : PionException("Service configuration option does not define a name: ", service_id) {}
00093 };
00094
00096 class MissingPortException : public PionException {
00097 public:
00098 MissingPortException(const std::string& server_id)
00099 : PionException("Server configuration does not define a port number: ", server_id) {}
00100 };
00101
00103 class UnknownAuthTypeException : public PionException {
00104 public:
00105 UnknownAuthTypeException(const std::string& server_id)
00106 : PionException("Server configuration has unknown AuthType parameter: ", server_id) {}
00107 };
00108
00110 class SSLKeyException : public PionException {
00111 public:
00112 SSLKeyException(const std::string& key_file)
00113 : PionException("Unable to load SSL key file: ", key_file) {}
00114 };
00115
00117 class RedirectMissingSourceException : public PionException {
00118 public:
00119 RedirectMissingSourceException(const std::string& server_id)
00120 : PionException("Service configuration Redirect element does not specify a Source: ", server_id) {}
00121 };
00122
00124 class RedirectMissingTargetException : public PionException {
00125 public:
00126 RedirectMissingTargetException(const std::string& server_id)
00127 : PionException("Service configuration Redirect element does not specify a Target: ", server_id) {}
00128 };
00129
00131 class WebServiceException : public PionException {
00132 public:
00133 WebServiceException(const std::string& service_id, const std::string& error_msg)
00134 : PionException(std::string("Service (") + service_id,
00135 std::string("): ") + error_msg)
00136 {}
00137 };
00138
00140 class PlatformServiceNotFoundException : public PionException {
00141 public:
00142 PlatformServiceNotFoundException(const std::string& service_id)
00143 : PionException("No platform service found for identifier: ", service_id) {}
00144 };
00145
00151 ServiceManager(const pion::platform::VocabularyManager& vocab_mgr, PlatformConfig& platform_config);
00152
00154 virtual ~ServiceManager() { shutdown(); }
00155
00157 void shutdown(void);
00158
00160 virtual void openConfigFile(void);
00161
00167 virtual void writeServersXML(std::ostream& out) const;
00168
00175 bool writeServerXML(std::ostream& out, const std::string& server_id) const;
00176
00182 template<typename WorkFunction>
00183 inline void post(WorkFunction work_func) { m_scheduler.getIOService().post(work_func); }
00184
00186 inline boost::asio::io_service& getIOService(void) { return m_scheduler.getIOService(); }
00187
00189 inline boost::uint32_t getNumThreads(void) const { return m_scheduler.getNumThreads(); }
00190
00192 inline void setNumThreads(const boost::uint32_t n) { m_scheduler.setNumThreads(n); }
00193
00195 void updateCodecs(void);
00196
00198 void updateDatabases(void);
00199
00201 void updateReactors(void);
00202
00204 unsigned int getPort(void) const;
00205
00214 std::string addPlatformService(const xmlNodePtr config_ptr);
00215
00221 void removePlatformService(const std::string& service_id);
00222
00231 static xmlNodePtr createPlatformServiceConfig(const char *buf, std::size_t len) {
00232 return ConfigManager::createResourceConfig(PLATFORM_SERVICE_ELEMENT_NAME, buf, len);
00233 }
00234
00235 protected:
00236
00248 virtual void addPluginNoLock(const std::string& plugin_id,
00249 const std::string& plugin_name,
00250 const xmlNodePtr config_ptr)
00251 {
00252 try {
00253 PlatformService *new_plugin_ptr = m_plugins.load(plugin_id, plugin_name);
00254 new_plugin_ptr->setId(plugin_id);
00255 new_plugin_ptr->setServiceManager(*this);
00256 new_plugin_ptr->setPlatformConfig(m_platform_config);
00257 if (config_ptr != NULL) {
00258 pion::platform::VocabularyPtr vocab_ptr(m_vocab_mgr.getVocabulary());
00259 new_plugin_ptr->setConfig(*vocab_ptr, config_ptr);
00260 }
00261
00262 pion::net::HTTPServerPtr server_ptr = m_servers[new_plugin_ptr->getServerId()];
00263 server_ptr->addResource(new_plugin_ptr->getResource(), boost::ref(*new_plugin_ptr));
00264 } catch (PionPlugin::PluginNotFoundException&) {
00265 throw;
00266 } catch (std::exception& e) {
00267 throw PluginException(e.what());
00268 }
00269 }
00270
00271 private:
00272
00282 void getWebServiceConfig(xmlNodePtr service_node, const std::string& server_id,
00283 std::string& service_id, std::string& plugin_type,
00284 std::string& http_resource);
00285
00293 static void handleServerError(pion::net::HTTPRequestPtr& http_request,
00294 pion::net::TCPConnectionPtr& tcp_conn,
00295 const std::string& error_msg);
00296
00297 void addWebService(xmlNodePtr service_node, const std::string& server_id);
00298
00299
00301 typedef std::map<std::string, pion::net::HTTPServerPtr> ServerMap;
00302
00304 typedef PluginManager<pion::net::WebService> WebServiceManager;
00305
00307 typedef PluginManager<PlatformService> PlatformServiceManager;
00308
00309
00311 static const boost::uint32_t DEFAULT_NUM_THREADS;
00312
00314 static const std::string DEFAULT_CONFIG_FILE;
00315
00317 static const std::string SERVER_ELEMENT_NAME;
00318
00320 static const std::string WEB_SERVICE_ELEMENT_NAME;
00321
00323 static const std::string PLATFORM_SERVICE_ELEMENT_NAME;
00324
00326 static const std::string PORT_ELEMENT_NAME;
00327
00329 static const std::string SSL_KEY_ELEMENT_NAME;
00330
00332 static const std::string REDIRECT_ELEMENT_NAME;
00333
00335 static const std::string REDIRECT_SOURCE_ELEMENT_NAME;
00336
00338 static const std::string REDIRECT_TARGET_ELEMENT_NAME;
00339
00341 static const std::string WEB_SERVICE_RESOURCE_ELEMENT_NAME;
00342
00344 static const std::string WEB_SERVICE_SERVER_ELEMENT_NAME;
00345
00347 static const std::string OPTION_ELEMENT_NAME;
00348
00350 static const std::string AUTH_ELEMENT_NAME;
00351
00353 static const std::string AUTH_RESTRICT_ELEMENT_NAME;
00354
00356 static const std::string AUTH_PERMIT_ELEMENT_NAME;
00357
00359 static const std::string AUTH_TYPE_ELEMENT_NAME;
00360
00362 static const std::string AUTH_LOGIN_ELEMENT_NAME;
00363
00365 static const std::string AUTH_LOGOUT_ELEMENT_NAME;
00366
00368 static const std::string AUTH_REDIRECT_ELEMENT_NAME;
00369
00371 static const std::string NAME_ATTRIBUTE_NAME;
00372
00374 PlatformConfig & m_platform_config;
00375
00377 PionSingleServiceScheduler m_scheduler;
00378
00380 ServerMap m_servers;
00381
00383 WebServiceManager m_web_services;
00384
00386 mutable boost::mutex m_mutex;
00387 };
00388
00389
00390 }
00391 }
00392
00393 #endif