Branch data Line data Source code
1 : : /*
2 : : * Copyright 2006-2010 Savarese Software Research Corporation
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * https://www.savarese.com/software/ApacheLicense-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : /**
18 : : * @file
19 : : * This header defines the WebService class.
20 : : */
21 : :
22 : : #ifndef __SSRC_WSPR_WS_SERVICE_H
23 : : #define __SSRC_WSPR_WS_SERVICE_H
24 : :
25 : : #include <ssrc/wispers/service/service.h>
26 : : #include <ssrc/wispers/ws/types.h>
27 : : #include <ssrc/wispers/ws/ActionConfig.h>
28 : :
29 : : __BEGIN_NS_SSRC_WSPR_WS
30 : :
31 : : using namespace NS_SSRC_WSPR_SERVICE;
32 : :
33 : : void validate_call(const ActionConfig & action,
34 : : const call_handler_type & call_handler,
35 : : const WebServiceCall & wc,
36 : : const MessageInfo & msginfo)
37 : : SSRC_DECL_THROW(std:::invalid_argument);
38 : :
39 : : #define WS_DELEGATE_ONE_WAY_CALL(call, impl, function_ptr) \
40 : : set_call_handler_one_way(call, boost::bind(function_ptr, impl, _1, _2))
41 : : #define WS_DELEGATE_TWO_WAY_CALL(call, impl, function_ptr) \
42 : : set_call_handler_two_way(call, boost::bind(function_ptr, impl, _1, _2))
43 : : #define WS_DELEGATE_ONE_WAY_CALL_WITH_PARAM(call, ws_type, param_type, impl, function_ptr) \
44 : : set_call_handler_one_way(call, boost::bind(NS_SSRC_WSPR_WS::ws_call<ws_type, param_type>, impl, function_ptr, _1, _2))
45 : : #define WS_DELEGATE_TWO_WAY_CALL_WITH_PARAM(call, ws_type, param_type, impl, function_ptr) \
46 : : set_call_handler_two_way(call, boost::bind(NS_SSRC_WSPR_WS::ws_call<ws_type, param_type>, impl, function_ptr, _1, _2))
47 : :
48 : : #define WS_ONE_WAY_CALL(call, function_ptr) \
49 : : WS_DELEGATE_ONE_WAY_CALL(call, this, function_ptr)
50 : : #define WS_TWO_WAY_CALL(call, function_ptr) \
51 : : WS_DELEGATE_TWO_WAY_CALL(call, this, function_ptr)
52 : : #define WS_ONE_WAY_CALL_WITH_PARAM(call, ws_type, param_type, function_ptr) \
53 : : WS_DELEGATE_ONE_WAY_CALL_WITH_PARAM(call, ws_type, param_type, this, function_ptr)
54 : : #define WS_TWO_WAY_CALL_WITH_PARAM(call, ws_type, param_type, function_ptr) \
55 : : WS_DELEGATE_TWO_WAY_CALL_WITH_PARAM(call, ws_type, param_type, this, function_ptr)
56 : :
57 : :
58 : : #define WS_DELEGATE_ACTION(action, impl, function_ptr) \
59 : : set_action_handler(action, boost::bind(function_ptr, impl, _1, _2))
60 : : #define WS_ACTION(action, function_ptr) \
61 : : WS_DELEGATE_ACTION(action, this, function_ptr)
62 : :
63 : : #define WS_DELEGATE_ACTION_WITH_PARAM(action, ws_type, param_type, impl, function_ptr) \
64 : : set_action_handler(action, boost::bind(NS_SSRC_WSPR_WS::ws_call<ws_type, param_type>, impl, function_ptr, _1, _2))
65 : : #define WS_ACTION_WITH_PARAM(action, ws_type, param_type, function_ptr) \
66 : : WS_DELEGATE_ACTION_WITH_PARAM(action, ws_type, param_type, this, function_ptr)
67 : :
68 : : class WebService : public ServiceProtocolProcessor {
69 : : friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>;
70 : : typedef ServiceProtocolProcessor super;
71 : :
72 : : public:
73 : : typedef WebServiceProtocol protocol_traits;
74 : :
75 : : protected:
76 : : WISP_IMPORT(protocol_traits, parameter_map);
77 : : WISP_IMPORT(protocol_traits, MessageOneWay);
78 : : WISP_IMPORT(protocol_traits, MessageTwoWay);
79 : : WISP_IMPORT(protocol_traits, MessageResponse);
80 : : WISP_IMPORT(protocol_traits, MessageDeliverEvent);
81 : : WISP_IMPORT(protocol_traits, MessageDeliverEvents);
82 : : WISP_IMPORT(protocol_traits, CallOneWay);
83 : : WISP_IMPORT(protocol_traits, CallTwoWay);
84 : : WISP_IMPORT(protocol_traits, CallResponse);
85 : : WISP_IMPORT(protocol_traits, CallDeliverEvent);
86 : : WISP_IMPORT(protocol_traits, CallDeliverEvents);
87 : :
88 : : // We need to hold on to ActionConfig references for validated calls.
89 : : boost::ptr_vector<ActionConfig> _actions;
90 : :
91 : : private:
92 : :
93 : : call_handler_map _call_handlers_one_way;
94 : : call_handler_map _call_handlers_two_way;
95 : :
96 : 0 : void reply_after_call_error(const WebServiceCall & call,
97 : : const MessageInfo & msginfo,
98 : : const string & error = "")
99 : : {
100 : 0 : MessageResponse response(call.session, 0);
101 [ # # ]: 0 : response.set_error(error);
102 [ # # ]: 0 : _caller.reply<CallResponse>(msginfo.sender(), msginfo.token(), response);
103 : 0 : }
104 : :
105 : : protected:
106 : :
107 : : ActionConfig & new_action(const Properties & action_map, const string & key)
108 : : SSRC_DECL_THROW(std:::domain_error);
109 : :
110 : : void clear_call_handlers();
111 : : bool set_call_handler_one_way(const string & call,
112 : : const call_handler_type & call_handler);
113 : : bool set_call_handler_two_way(const string & call,
114 : : const call_handler_type & call_handler);
115 : : bool set_action_handler(ActionConfig & action,
116 : : const call_handler_type & call_handler);
117 : :
118 : : // Allow one_way_call and two_way_call to be overridden in case we
119 : : // want to change the behavior (for example, dynamic discovery of
120 : : // call functions in a scripting context based on name). Could
121 : : // refactor and put the handler map stuff in a WebService subclass.
122 : : //virtual
123 : 0 : void one_way_call(const WebServiceCall & call, const MessageInfo & msginfo) {
124 : : call_handler_map::const_iterator it =
125 : 0 : _call_handlers_one_way.find(call.call);
126 : :
127 [ # # ]: 0 : if(it != _call_handlers_one_way.end()) {
128 : : try {
129 [ # # # # ]: 0 : it->second(call, msginfo);
130 : 0 : } catch(const std::exception & e) {
131 : : #ifdef WSPR_DEBUG
132 [ # # # # : 0 : std::cerr << "one_way_call EXCEPTION: " << e.what() << std::endl;
# # ]
133 : : #endif
134 : : // TODO: log error.
135 [ # # ]: 0 : } catch(...) {
136 : : #ifdef WSPR_DEBUG
137 [ # # ]: 0 : std::cerr << "one_way_call unknown exception\n";
138 : : #endif
139 : : // TODO: log error.
140 : : }
141 : : }
142 : :
143 : : // TODO: Do we just ignore unsupported call attempt, log, delegate
144 : : // to virtual error handling function?
145 : 0 : }
146 : :
147 : : //virtual
148 : 1 : void two_way_call(const WebServiceCall & call, const MessageInfo & msginfo) {
149 : : call_handler_map::const_iterator it =
150 : 1 : _call_handlers_two_way.find(call.call);
151 : :
152 [ + - ]: 1 : if(it != _call_handlers_two_way.end()) {
153 : : try {
154 [ + - + - ]: 1 : it->second(call, msginfo);
155 : 0 : } catch(const std::exception & e) {
156 : : #ifdef WSPR_DEBUG
157 [ # # # # : 0 : std::cerr << "two_way_call EXCEPTION: " << e.what() << std::endl;
# # ]
158 : : #endif
159 : : // TODO: log error.
160 [ # # # # : 0 : reply_after_call_error(call, msginfo, e.what());
# # ]
161 [ # # ]: 0 : } catch(...) {
162 : : #ifdef WSPR_DEBUG
163 [ # # ]: 0 : std::cerr << "two_way_call unknown exception\n";
164 : : #endif
165 : : // TODO: log error.
166 [ # # # # : 0 : reply_after_call_error(call, msginfo);
# # ]
167 : : }
168 : : }
169 : :
170 : : // TODO: Do we just ignore unsupported call attempt, log, delegate
171 : : // to virtual error handling function?
172 : 1 : }
173 : :
174 : 0 : void process_request(const MessageOneWay & msg,
175 : : const MessageInfo & msginfo)
176 : : {
177 : 0 : one_way_call(msg.call, msginfo);
178 : 0 : }
179 : :
180 : 1 : void process_request(const MessageTwoWay & msg,
181 : : const MessageInfo & msginfo)
182 : : {
183 : 1 : two_way_call(msg.call, msginfo);
184 : 1 : }
185 : :
186 : : public:
187 : :
188 : : explicit WebService(super::caller_type & caller);
189 : :
190 [ + - + - : 1 : virtual ~WebService() { }
+ - - + ]
191 : : };
192 : :
193 : : __END_NS_SSRC_WSPR_WS
194 : :
195 : : #endif
|