1 /*
2 * Copyright 1999-2006 University of Chicago
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 * http://www.apache.org/licenses/LICENSE-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
19 #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
20
21 #include "globus_i_soap_client.h"
22
23 static
24 void
25 globus_l_soap_client_blocking_request_callback(
26 globus_soap_client_handle_t request,
27 void * arg,
28 globus_result_t result);
29
30 static
31 void
32 globus_l_soap_client_blocking_response_callback(
33 globus_soap_client_handle_t request,
34 void * arg,
35 globus_result_t result,
36 void * output,
37 int fault_type,
38 xsd_any * fault);
39 #endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */
40
41 /**
42 * Invoke a SOAP operation in a nonblocking way.
43 * @ingroup globus_soap_client
44 * @internal
45 *
46 * Begins processing a SOAP operation and will handle both the message
47 * request and (if applicable) the server's response to the operation
48 * request. The @a callback function will be invoked once the operation
49 * has completed.
50 *
51 * @param handle
52 * The SOAP client handle to use for state while processing this
53 * request.
54 * @param endpoint
55 * The URI of the endpoint to send the SOAP operation request to.
56 * @param operation
57 * The description of the operation and its serializers and deserializers.
58 * This must not be modified until the operation and its response have
59 * been processed by the client handle.
60 * @param input
61 * The operation's input element value. A copy of this value will be made
62 * by this function, so this parameter's value may be freed or otherwise
63 * modified by the caller after this function returns.
64 * @param callback
65 * Callback function to invoke once the operation response has been handled.
66 * @param user_args
67 * Application-specific argument to the callback function.
68 *
69 * @retval GLOBUS_SUCCESS
70 * Processing of this operation has begun successfully.
71 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_CLIENT_ALREADY_INVOKED
72 * Processing the operation failed because the client is already actively
73 * handling a request or response.
74 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_INIT_FAILED
75 * Processing the operation failed because the client could not initialize
76 * some part of its data.
77 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_CLIENT_REQUEST_FAILED
78 * Processing the operation failed because the client could not initialize
79 * some part of its data.
80 */
81 globus_result_t
82 globus_soap_client_operation_register(
83 globus_soap_client_handle_t handle,
84 const char * endpoint,
85 const globus_soap_client_operation_t *
86 operation,
87 void * input,
88 globus_soap_client_response_callback_func_t
89 callback,
90 void * user_args)
91 12931 {
92 12931 globus_result_t result = GLOBUS_SUCCESS;
93
94 12931 handle->response.callback = callback;
95 12931 handle->response.args = user_args;
96
97 12931 result = globus_soap_client_register_request(
98 handle,
99 endpoint,
100 operation,
101 input,
102 globus_l_soap_client_blocking_request_callback,
103 handle);
104
105 12931 return result;
106 }
107 /* globus_soap_client_operation_register() */
108
109 /**
110 * Invoke a SOAP operation in a blocking way.
111 * @ingroup globus_soap_client
112 * @internal
113 *
114 * Process a SOAP operation and will handle both the message
115 * request and (if applicable) the server's response to the operation
116 * request. This function will not return until both are handled. When this
117 * function returns, the @a output, @a fault, and @a fault_type parameters
118 * will be modified to point to values returned from the service. The
119 * @a output and @a fault must be freed by the caller.
120 *
121 * @param handle
122 * The SOAP client handle to use for state while processing this
123 * request.
124 * @param endpoint
125 * The URI of the endpoint to send the SOAP operation request to.
126 * @param operation
127 * The description of the operation and its serializers and deserializers.
128 * This must not be modified until the operation and its response have
129 * been processed by the client handle.
130 * @param input
131 * The operation's input element value.
132 * @param output
133 * A pointer to be set to the operation's output elmeent value. The value
134 * which this is set to must be freed by the caller.
135 * @param fault_type
136 * A pointer to be set to the enumeration value of the fault type if a fault
137 * was detected by the service while processing the operation.
138 * @param fault
139 * A pointer to be set to the value of the fault which occurred. This will
140 * be set to NULL if no fault occurred. If this is set to a non-NULL value,
141 * the value must be freed by the caller.
142 *
143 * @retval GLOBUS_SUCCESS
144 * Processing of this operation has begun successfully.
145 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_CLIENT_ALREADY_INVOKED
146 * Processing the operation failed because the client is already actively
147 * handling a request or response.
148 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_INIT_FAILED
149 * Processing the operation failed because the client could not initialize
150 * some part of its data.
151 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_CLIENT_REQUEST_FAILED
152 * Processing the operation failed because the client could not initialize
153 * some part of its data.
154 */
155 globus_result_t
156 globus_soap_client_operation(
157 globus_soap_client_handle_t handle,
158 const char * endpoint,
159 const globus_soap_client_operation_t *
160 operation,
161 void * input,
162 void ** output,
163 int * fault_type,
164 xsd_any ** fault)
165 12931 {
166 12931 globus_result_t result = GLOBUS_SUCCESS;
167
168 12931 if (output != NULL)
169 {
170 12931 *output = NULL;
171 }
172 12931 if (fault_type != NULL)
173 {
174 12931 *fault_type = 0;
175 }
176
177 12931 if (fault != NULL)
178 {
179 12931 *fault = NULL;
180 }
181
182 12931 result = globus_soap_client_operation_register(
183 handle,
184 endpoint,
185 operation,
186 input,
187 globus_l_soap_client_blocking_response_callback,
188 NULL);
189
190 12931 if(result != GLOBUS_SUCCESS)
191 {
192 0 goto exit;
193 }
194
195 12931 globus_mutex_lock(&handle->mutex);
196 64676 while(!handle->done)
197 {
198 38814 globus_cond_wait(&handle->cond, &handle->mutex);
199 }
200 12931 handle->done = GLOBUS_FALSE;
201 12931 globus_mutex_unlock(&handle->mutex);
202
203 12931 result = handle->response.result;
204 12931 if(result != GLOBUS_SUCCESS)
205 {
206 296 if (fault_type)
207 {
208 296 *fault_type = handle->response.fault_type;
209 }
210 296 if (fault)
211 {
212 296 *fault = handle->response.fault;
213 }
214
215 296 handle->response.fault = NULL;
216 296 handle->response.fault_type = 0;
217 296 handle->response.result = GLOBUS_SUCCESS;
218
219 296 goto exit;
220 }
221
222
223 12635 if (output != NULL &&
224 operation->output_type_info != NULL &&
225 handle->response.output != NULL)
226 {
227 12635 *output = handle->response.output;
228
229 12635 handle->response.output = NULL;
230 }
231
232 12931 exit:
233 12931 return result;
234 }
235 /* globus_soap_client_operation() */
236
237 #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
238 static
239 void
240 globus_l_soap_client_blocking_request_callback(
241 globus_soap_client_handle_t handle,
242 void * arg,
243 globus_result_t error)
244 12931 {
245 12931 globus_result_t result = GLOBUS_SUCCESS;
246
247 12970 if(error != GLOBUS_SUCCESS ||
248 globus_soap_message_is_cancelled(handle->message))
249 {
250 39 handle->response.callback(
251 handle,
252 handle->response.args,
253 error,
254 NULL,
255 0,
256 NULL);
257 }
258 else
259 {
260 12892 result = globus_soap_client_register_response(
261 handle,
262 handle->response.callback,
263 handle->response.args);
264
265 12892 if(result != GLOBUS_SUCCESS)
266 {
267 0 handle->response.callback(
268 handle,
269 handle->response.args,
270 result,
271 NULL,
272 0,
273 NULL);
274 }
275
276 }
277 12931 }
278 /* globus_l_soap_client_blocking_request_callback() */
279
280 static
281 void
282 globus_l_soap_client_blocking_response_callback(
283 globus_soap_client_handle_t handle,
284 void * arg,
285 globus_result_t error,
286 void * output,
287 int fault_type,
288 xsd_any * fault)
289 12931 {
290 12931 globus_mutex_lock(&handle->mutex);
291 12931 handle->response.result = error;
292 12931 handle->done = GLOBUS_TRUE;
293 12931 globus_cond_signal(&handle->cond);
294 12931 globus_mutex_unlock(&handle->mutex);
295 12931 }
296 /* globus_l_soap_client_blocking_response_callback() */