platform/server/PlatformService.hpp

00001 // ------------------------------------------------------------------------
00002 // Pion is a development platform for building Reactors that process Events
00003 // ------------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Pion is free software: you can redistribute it and/or modify it under the
00007 // terms of the GNU Affero General Public License as published by the Free
00008 // Software Foundation, either version 3 of the License, or (at your option)
00009 // any later version.
00010 //
00011 // Pion is distributed in the hope that it will be useful, but WITHOUT ANY
00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013 // FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
00014 // more details.
00015 //
00016 // You should have received a copy of the GNU Affero General Public License
00017 // along with Pion.  If not, see <http://www.gnu.org/licenses/>.
00018 //
00019 
00020 #ifndef __PION_PLATFORMSERVICE_HEADER__
00021 #define __PION_PLATFORMSERVICE_HEADER__
00022 
00023 #include <string>
00024 #include <libxml/tree.h>
00025 #include <pion/PionConfig.hpp>
00026 #include <pion/PionException.hpp>
00027 #include <pion/PionLogger.hpp>
00028 #include <pion/net/WebService.hpp>
00029 #include <pion/net/HTTPRequest.hpp>
00030 #include <pion/net/HTTPServer.hpp>
00031 #include <pion/platform/PlatformPlugin.hpp>
00032 
00033 
00034 namespace pion {        // begin namespace pion
00035 namespace server {      // begin namespace server (Pion Server)
00036 
00037 
00038 // forward declarations to avoid header dependencies
00039 class PlatformConfig;
00040 
00041 
00045 class PION_SERVER_API PlatformService
00046     : public pion::platform::PlatformPlugin,
00047     public pion::net::WebService
00048 {
00049 public:
00050 
00052     class MissingConfigException : public PionException {
00053     public:
00054         MissingConfigException(const std::string& service_id)
00055             : PionException("Platform service missing configuration: ", service_id) {}
00056     };
00057 
00059     class ServerIdOfServiceUnspecifiedException : public PionException {
00060     public:
00061         ServerIdOfServiceUnspecifiedException(const std::string& service_id)
00062             : PionException("Service configuration includes a Service without a Server identifier: ", service_id) {}
00063     };
00064 
00066     class EmptyServiceResourceException : public PionException {
00067     public:
00068         EmptyServiceResourceException(const std::string& service_id)
00069             : PionException("Service configuration does not define a resource: ", service_id) {}
00070     };
00071 
00072 
00074     PlatformService(const std::string& logger) : m_logger(PION_GET_LOGGER(logger)), m_config_ptr(NULL) {}
00075 
00077     virtual ~PlatformService() {}
00078     
00087     virtual void operator()(pion::net::HTTPRequestPtr& request,
00088                             pion::net::TCPConnectionPtr& tcp_conn) = 0;
00089 
00097     virtual void setConfig(const pion::platform::Vocabulary& v,
00098                            const xmlNodePtr config_ptr);
00099 
00100     inline virtual void setPlatformConfig(PlatformConfig& platform_cfg) {
00101         m_config_ptr = &platform_cfg;
00102     }
00103 
00104     inline void setServerId(const std::string& server_id) { m_server_id = server_id; }
00105 
00106     inline std::string getServerId(void) { return m_server_id; }
00107 
00114     virtual void updateCodecs(PlatformConfig& platform_cfg) {}
00115     
00122     virtual void updateDatabases(PlatformConfig& platform_cfg) {}
00123 
00130     virtual void updateReactors(PlatformConfig& platform_cfg) {}
00131 
00140     virtual bool accessAllowed(xmlNodePtr permission_config_ptr, const std::string& id) const {
00141         // By default, permission is granted solely based on whether a Permission node of the appropriate type was found.
00142         return permission_config_ptr != NULL;
00143     }
00144 
00146     virtual std::string getPermissionType(void) const { return ""; }
00147 
00148     
00149 protected:
00150     
00152     typedef std::vector<std::string>    PathBranches;
00153     
00154     
00161     void splitPathBranches(PathBranches& branches, const std::string& resource);
00162     
00163     
00165     inline const PlatformConfig& getConfig(void) const {
00166         if (m_config_ptr == NULL)
00167             throw MissingConfigException(getId());
00168         return *m_config_ptr;
00169     }
00170     
00172     inline PlatformConfig& getConfig(void) {
00173         if (m_config_ptr == NULL)
00174             throw MissingConfigException(getId());
00175         return *m_config_ptr;
00176     }
00177 
00178     // logs an error and sends a 400 (Bad Request) response
00179     virtual void handleBadRequest(pion::net::HTTPRequestPtr& request, pion::net::TCPConnectionPtr& tcp_conn, const std::string& error_msg) {
00180         PION_LOG_ERROR(m_logger, error_msg);
00181         pion::net::HTTPServer::handleBadRequest(request, tcp_conn);
00182     }
00183 
00184     // logs an error and sends a 403 (Forbidden) response
00185     virtual void handleForbiddenRequest(pion::net::HTTPRequestPtr& request, pion::net::TCPConnectionPtr& tcp_conn, const std::string& error_msg) {
00186         PION_LOG_ERROR(m_logger, error_msg << " (user: " << request->getUser()->getUsername() << ")");
00187         pion::net::HTTPServer::handleForbiddenRequest(request, tcp_conn, error_msg);
00188     }
00189 
00190     // logs an error and sends a 404 (Not Found) response
00191     virtual void handleNotFoundRequest(pion::net::HTTPRequestPtr& request, pion::net::TCPConnectionPtr& tcp_conn) {
00192         PION_LOG_ERROR(m_logger, "The requested URL was not found: " << request->getResource());
00193         pion::net::HTTPServer::handleNotFoundRequest(request, tcp_conn);
00194     }
00195 
00196     // logs an error and sends a 405 (Method Not Allowed) response
00197     virtual void handleMethodNotAllowed(pion::net::HTTPRequestPtr& request, pion::net::TCPConnectionPtr& tcp_conn, const std::string& allowed_methods) {
00198         std::string error_msg = "Method " + request->getMethod() + " not allowed for requested URL: " + request->getResource();
00199         PION_LOG_ERROR(m_logger, error_msg);
00200         pion::net::HTTPServer::handleMethodNotAllowed(request, tcp_conn, allowed_methods);
00201     }
00202 
00204     PionLogger          m_logger;
00205 
00206 private:
00207 
00209     PlatformConfig      *m_config_ptr;
00210 
00211     std::string m_server_id;
00212 
00214     static const std::string        SERVER_ELEMENT_NAME;
00215 
00217     static const std::string        RESOURCE_ELEMENT_NAME;
00218 };
00219 
00220 
00221 //
00222 // The following symbols must be defined for any platform service that you would
00223 // like to be able to load dynamically using the ServiceManager.
00224 //
00225 // Make sure that you replace "PlatformService" with the name of your derived
00226 // class. This name must also match the name of the object file (excluding the
00227 // extension).  These symbols must be linked into your service's object file,
00228 // not included in any headers that it may use (declarations are OK in headers
00229 // but not the definitions).
00230 //
00231 // The "pion_create" function is used to create new instances of your service.
00232 // The "pion_destroy" function is used to destroy instances of your service.
00233 //
00234 // extern "C" PlatformService *pion_create_PlatformService(void) {
00235 //      return new PlatformService;
00236 // }
00237 //
00238 // extern "C" void pion_destroy_PlatformService(PlatformService *service_ptr) {
00239 //      delete service_ptr;
00240 // }
00241 //
00242     
00243     
00244 }   // end namespace server
00245 }   // end namespace pion
00246 
00247 #endif

Generated on Wed Apr 13 16:38:34 2011 for pion-platform by  doxygen 1.4.7