Savarese Software Research Corporation
ws/service.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2010 Savarese Software Research Corporation
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     https://www.savarese.com/software/ApacheLicense-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00022 #ifndef __SSRC_WSPR_WS_SERVICE_H
00023 #define __SSRC_WSPR_WS_SERVICE_H
00024 
00025 #include <ssrc/wispers/service/service.h>
00026 #include <ssrc/wispers/ws/types.h>
00027 #include <ssrc/wispers/ws/ActionConfig.h>
00028 
00029 __BEGIN_NS_SSRC_WSPR_WS
00030 
00031 using namespace NS_SSRC_WSPR_SERVICE;
00032 
00033 void validate_call(const ActionConfig & action,
00034                    const call_handler_type & call_handler,
00035                    const WebServiceCall & wc,
00036                    const MessageInfo & msginfo)
00037   SSRC_DECL_THROW(std:::invalid_argument);
00038 
00039 #define WS_DELEGATE_ONE_WAY_CALL(call, impl, function_ptr)                \
00040   set_call_handler_one_way(call, boost::bind(function_ptr, impl, _1, _2))
00041 #define WS_DELEGATE_TWO_WAY_CALL(call, impl, function_ptr) \
00042   set_call_handler_two_way(call, boost::bind(function_ptr, impl, _1, _2))
00043 #define WS_DELEGATE_ONE_WAY_CALL_WITH_PARAM(call, ws_type, param_type, impl, function_ptr) \
00044   set_call_handler_one_way(call, boost::bind(NS_SSRC_WSPR_WS::ws_call<ws_type, param_type>, impl, function_ptr, _1, _2))
00045 #define WS_DELEGATE_TWO_WAY_CALL_WITH_PARAM(call, ws_type, param_type, impl, function_ptr) \
00046   set_call_handler_two_way(call, boost::bind(NS_SSRC_WSPR_WS::ws_call<ws_type, param_type>, impl, function_ptr, _1, _2))
00047 
00048 #define WS_ONE_WAY_CALL(call, function_ptr) \
00049   WS_DELEGATE_ONE_WAY_CALL(call, this, function_ptr)
00050 #define WS_TWO_WAY_CALL(call, function_ptr) \
00051   WS_DELEGATE_TWO_WAY_CALL(call, this, function_ptr)
00052 #define WS_ONE_WAY_CALL_WITH_PARAM(call, ws_type, param_type, function_ptr) \
00053   WS_DELEGATE_ONE_WAY_CALL_WITH_PARAM(call, ws_type, param_type, this, function_ptr)
00054 #define WS_TWO_WAY_CALL_WITH_PARAM(call, ws_type, param_type, function_ptr) \
00055   WS_DELEGATE_TWO_WAY_CALL_WITH_PARAM(call, ws_type, param_type, this, function_ptr)
00056 
00057 
00058 #define WS_DELEGATE_ACTION(action, impl, function_ptr) \
00059   set_action_handler(action, boost::bind(function_ptr, impl, _1, _2))
00060 #define WS_ACTION(action, function_ptr) \
00061   WS_DELEGATE_ACTION(action, this, function_ptr)
00062 
00063 #define WS_DELEGATE_ACTION_WITH_PARAM(action, ws_type, param_type, impl, function_ptr) \
00064   set_action_handler(action, boost::bind(NS_SSRC_WSPR_WS::ws_call<ws_type, param_type>, impl, function_ptr, _1, _2))
00065 #define WS_ACTION_WITH_PARAM(action, ws_type, param_type, function_ptr) \
00066   WS_DELEGATE_ACTION_WITH_PARAM(action, ws_type, param_type, this, function_ptr)
00067 
00068 class WebService : public ServiceProtocolProcessor {
00069   friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>;
00070   typedef ServiceProtocolProcessor super;
00071 
00072 public:
00073   typedef WebServiceProtocol protocol_traits;
00074 
00075 protected:
00076   WISP_IMPORT(protocol_traits, parameter_map);
00077   WISP_IMPORT(protocol_traits, MessageOneWay);
00078   WISP_IMPORT(protocol_traits, MessageTwoWay);
00079   WISP_IMPORT(protocol_traits, MessageResponse);
00080   WISP_IMPORT(protocol_traits, MessageDeliverEvent);
00081   WISP_IMPORT(protocol_traits, MessageDeliverEvents);
00082   WISP_IMPORT(protocol_traits, CallOneWay);
00083   WISP_IMPORT(protocol_traits, CallTwoWay);
00084   WISP_IMPORT(protocol_traits, CallResponse);
00085   WISP_IMPORT(protocol_traits, CallDeliverEvent);
00086   WISP_IMPORT(protocol_traits, CallDeliverEvents);
00087 
00088   // We need to hold on to ActionConfig references for validated calls.
00089   boost::ptr_vector<ActionConfig> _actions;
00090 
00091 private:
00092 
00093   call_handler_map _call_handlers_one_way;
00094   call_handler_map _call_handlers_two_way;
00095 
00096   void reply_after_call_error(const WebServiceCall & call,
00097                               const MessageInfo & msginfo,
00098                               const string & error = "")
00099   {
00100     MessageResponse response(call.session, 0);
00101     response.set_error(error);
00102     _caller.reply<CallResponse>(msginfo.sender(), msginfo.token(), response);
00103   }
00104 
00105 protected:
00106 
00107   ActionConfig & new_action(const Properties & action_map, const string & key)
00108     SSRC_DECL_THROW(std:::domain_error);
00109 
00110   void clear_call_handlers();
00111   bool set_call_handler_one_way(const string & call,
00112                                 const call_handler_type & call_handler);
00113   bool set_call_handler_two_way(const string & call,
00114                                 const call_handler_type & call_handler);
00115   bool set_action_handler(ActionConfig & action,
00116                           const call_handler_type & call_handler);
00117 
00118   // Allow one_way_call and two_way_call to be overridden in case we
00119   // want to change the behavior (for example, dynamic discovery of
00120   // call functions in a scripting context based on name).  Could
00121   // refactor and put the handler map stuff in a WebService subclass.
00122   //virtual
00123   void one_way_call(const WebServiceCall & call, const MessageInfo & msginfo) {
00124     call_handler_map::const_iterator it =
00125       _call_handlers_one_way.find(call.call);
00126 
00127     if(it != _call_handlers_one_way.end()) {
00128       try {
00129         it->second(call, msginfo);
00130       } catch(const std::exception & e) {
00131 #ifdef WSPR_DEBUG
00132         std::cerr << "one_way_call EXCEPTION: " << e.what() << std::endl;
00133 #endif
00134         // TODO: log error.
00135       } catch(...) {
00136 #ifdef WSPR_DEBUG
00137         std::cerr << "one_way_call unknown exception\n";
00138 #endif
00139         // TODO: log error.
00140       }
00141     }
00142 
00143     // TODO: Do we just ignore unsupported call attempt, log, delegate
00144     // to virtual error handling function?
00145   }
00146 
00147   //virtual
00148   void two_way_call(const WebServiceCall & call, const MessageInfo & msginfo) {
00149     call_handler_map::const_iterator it =
00150       _call_handlers_two_way.find(call.call);
00151 
00152     if(it != _call_handlers_two_way.end()) {
00153       try {
00154         it->second(call, msginfo);
00155       } catch(const std::exception & e) {
00156 #ifdef WSPR_DEBUG
00157         std::cerr << "two_way_call EXCEPTION: " << e.what() << std::endl;
00158 #endif
00159         // TODO: log error.
00160         reply_after_call_error(call, msginfo, e.what());
00161       } catch(...) {
00162 #ifdef WSPR_DEBUG
00163         std::cerr << "two_way_call unknown exception\n";
00164 #endif
00165         // TODO: log error.
00166         reply_after_call_error(call, msginfo);
00167       }
00168     }
00169 
00170     // TODO: Do we just ignore unsupported call attempt, log, delegate
00171     // to virtual error handling function?
00172   }
00173 
00174   void process_request(const MessageOneWay & msg,
00175                        const MessageInfo & msginfo)
00176   {
00177     one_way_call(msg.call, msginfo);
00178   }
00179 
00180   void process_request(const MessageTwoWay & msg,
00181                        const MessageInfo & msginfo)
00182   {
00183     two_way_call(msg.call, msginfo);
00184   }
00185 
00186 public:
00187 
00188   explicit WebService(super::caller_type & caller);
00189 
00190   virtual ~WebService() { }
00191 };
00192 
00193 __END_NS_SSRC_WSPR_WS
00194 
00195 #endif

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.