1 /*
2  * Portions of this file Copyright 1999-2005 University of Chicago
3  * Portions of this file Copyright 1999-2005 The University of Southern California.
4  *
5  * This file or a portion of this file is licensed under the
6  * terms of the Globus Toolkit Public License, found at
7  * http://www.globus.org/toolkit/download/license.html.
8  * If you redistribute this file, with or without
9  * modifications, you must include this notice in the file.
10  */
11
12
13 #include "globus_service_engine.h"
14 #include "globus_service_registry.h"
15 #include "globus_wsrf_core_tools.h"
16 #include "globus_i_wsrf_core_tools.h"
17 #include "version.h"
18 #include "libxml/uri.h"
19 #include "globus_wsrf_resource.h"
20 #include "globus_error_string.h"
21 #include "wsbf_DescriptionType.h"
22 #include "globus_ws_addressing.h"
23
24
25 static int
26 globus_l_wsrf_core_tools_activate();
27
28 static int
29 globus_l_wsrf_core_tools_deactivate();
30
31 globus_module_descriptor_t              globus_l_wsrf_core_tools_module =
32 {
33     "globus_wsrf_core_tools_module",
34     globus_l_wsrf_core_tools_activate,
35     globus_l_wsrf_core_tools_deactivate,
36     NULL,
37     NULL,
38     &local_version
39 };
40
41 0 GlobusDebugDefine(GLOBUS_WSRF_CORE_TOOLS);
42
43
44
45 static int
46 globus_l_wsrf_core_tools_activate()
47 {
48 0     int                                 rc = 0;
49 0     GlobusFuncName(globus_l_wsrf_core_tools_activate);
50
51 0     rc = globus_module_activate(GLOBUS_COMMON_MODULE);
52 0     if(rc != GLOBUS_SUCCESS)
53     {
54 0         return rc;
55     }
56
57 0     GlobusDebugInit(GLOBUS_WSRF_CORE_TOOLS, DEBUG INFO TRACE WARN ERROR);
58 0     GlobusWSRFCoreToolsDebugEnter();
59
60 0     rc = globus_module_activate(GLOBUS_SOAP_MESSAGE_MODULE);
61 0     if(rc != GLOBUS_SUCCESS)
62     {
63 0         globus_module_deactivate(GLOBUS_COMMON_MODULE);
64         goto error_exit;
65     }
66
67 0     goto exit;
68
69  error_exit:
70
71 0     GlobusWSRFCoreToolsDebugExit();
72 0     GlobusDebugDestroy(GLOBUS_WSRF_CORE_TOOLS);
73 0     return rc;
74
75  exit:
76
77 0     GlobusWSRFCoreToolsDebugExit();
78 0     return rc;
79 }
80
81 static int
82 globus_l_wsrf_core_tools_deactivate()
83 0 {
84 0     int                                 rc = 0;
85 0     GlobusFuncName(globus_l_wsrf_core_tools_deactivate);
86 0     GlobusWSRFCoreToolsDebugEnter();
87
88 0     rc = globus_module_deactivate(GLOBUS_SOAP_MESSAGE_MODULE);
89 0     if(rc != GLOBUS_SUCCESS)
90     {
91 0         goto exit;
92     }
93
94  exit:
95
96 0     GlobusWSRFCoreToolsDebugExit();
97 0     GlobusDebugDestroy(GLOBUS_WSRF_CORE_TOOLS);
98 0     globus_module_deactivate(GLOBUS_COMMON_MODULE);
99
100 0     return rc;
101 }
102
103 #include "globus_xsd_primitives.h"
104 #include "globus_wsrf_core_tools.h"
105
106 globus_result_t
107 globus_wsrf_core_create_endpoint_reference(
108     globus_service_engine_t             engine,
109     const char *                        path,
110     xsd_any * *                         resource_id,
111     wsa_EndpointReferenceType   *       endpoint_reference)
112 46 {
113 46     globus_result_t                     result = GLOBUS_SUCCESS;
114 46     xsd_any *                           new_rp;
115 46     char *                              contact;
116 46     GlobusFuncName(globus_wsrf_core_create_endpoint_reference);
117 46     GlobusWSRFCoreToolsDebugEnter();
118     
119 46     globus_service_engine_get_contact(engine, &contact);
120
121 46     wsa_EndpointReferenceType_init_contents(endpoint_reference);
122
123 46     endpoint_reference->Address.base_value = 
124     globus_common_create_string("%s%s",
125                                 contact,
126                                 path);
127 46     globus_free(contact);
128     
129 46     wsa_ReferencePropertiesType_init(&endpoint_reference->ReferenceProperties);
130 46     new_rp = xsd_any_array_push(&endpoint_reference->ReferenceProperties->any);
131     
132 46     new_rp->value = (*resource_id)->value;
133 46     new_rp->element = (*resource_id)->element;
134 46     new_rp->any_info = (*resource_id)->any_info;
135
136 46     (*resource_id)->value = NULL;
137 46     (*resource_id)->element = NULL;
138 46     xsd_any_destroy(*resource_id);
139     
140 46     *resource_id = NULL;
141
142 46     GlobusWSRFCoreToolsDebugExit();
143 46     return result;
144 }
145
146 globus_result_t
147 globus_wsrf_core_unwrap_endpoint_reference(
148     const char *                        wrapped_uri,
149     xsd_QName *                         id_element,
150     wsa_EndpointReferenceType   *       endpoint_reference)
151 0 {
152 0     globus_result_t                     result = GLOBUS_SUCCESS;
153 0     xsd_any *                           new_rp;
154 0     xmlURIPtr                           parsed_uri;
155 0     GlobusFuncName(globus_wsrf_core_unwrap_endpoint_reference);
156 0     GlobusWSRFCoreToolsDebugEnter();
157     
158 0     parsed_uri = xmlParseURI(wrapped_uri);
159     
160 0     wsa_ReferencePropertiesType_init(&endpoint_reference->ReferenceProperties);
161 0     new_rp = xsd_any_array_push(&endpoint_reference->ReferenceProperties->any);
162    
163 0     xsd_string_copy_cstr((xsd_string **) &new_rp->value, parsed_uri->query);
164 0     xsd_QName_copy(&new_rp->element, id_element);
165 0     new_rp->any_info = &xsd_string_info;
166
167 0     xmlFree(parsed_uri->query);
168 0     parsed_uri->query = NULL; 
169 0     endpoint_reference->Address.base_value = xmlSaveUri(parsed_uri);
170
171 0     xmlFreeURI(parsed_uri);
172
173 0     GlobusWSRFCoreToolsDebugExit();
174 0     return result;
175 }
176
177 globus_result_t
178 globus_wsrf_core_wrap_endpoint_reference(
179     wsa_EndpointReferenceType *         endpoint_reference,
180     char **                             wrapped_uri)
181 0 {
182 0     globus_result_t                     result = GLOBUS_SUCCESS;
183 0     GlobusFuncName(globus_wsrf_core_wrap_endpoint_reference);
184 0     GlobusWSRFCoreToolsDebugEnter();
185
186     /* verify endpoint reference property is xsd_string type */
187
188 0     if(endpoint_reference->ReferenceProperties)
189     {
190 0         result = GlobusWSRFCoreToolsErrorNullReferenceProperty();
191 0         goto exit;
192     }
193     
194 0     if(endpoint_reference->ReferenceProperties->any.length != 1)
195     {
196 0         result = GlobusWSRFCoreToolsErrorReferencePropertiesWrongCount(
197             endpoint_reference->ReferenceProperties->any.length);
198 0         goto exit;
199     }
200
201 0     if(endpoint_reference->ReferenceProperties->any.elements[0].any_info !=
202        (&xsd_string_info))
203     {
204 0         result = GlobusWSRFCoreToolsErrorInvalidReferenceProperties(
205             endpoint_reference->ReferenceProperties->
206             any.elements[0].any_info->type);
207 0         goto exit;
208     }
209
210 0     *wrapped_uri = globus_common_create_string(
211         "%s?%s",
212         endpoint_reference->Address.base_value,
213         endpoint_reference->ReferenceProperties->any.elements[0].value);
214
215  exit:
216
217 0     GlobusWSRFCoreToolsDebugExit();
218 0     return result;
219 }
220
221 globus_result_t
222 globus_wsrf_core_get_resource(
223     globus_soap_message_handle_t        message,
224     globus_service_descriptor_t *       service,
225     globus_resource_t *                 resource)
226 2073 {
227 2073     globus_result_t                     result = GLOBUS_SUCCESS;
228 2073     char *                              id = NULL;
229 2073     wsa_EndpointReferenceType *         epr;
230 2073     GlobusFuncName(globus_wsrf_core_get_resource_id);
231 2073     GlobusWSRFCoreToolsDebugEnter();
232     
233 2073     epr = globus_soap_message_handle_get_attr(
234         message, 
235         WSADDR_EPR_KEY);
236 2073     if(!epr)
237     {
238 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
239             GLOBUS_SUCCESS, 
240             "No EndpointReference found "
241             "in message properties");
242 0         goto exit;
243     }
244
245 2073     result = service->get_resource_id(&epr->ReferenceProperties->any, &id);
246 2073     if(result != GLOBUS_SUCCESS)
247     {
248 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
249             result, "Failed to get resource id from ReferenceProperties");
250 0         goto exit;
251     }
252
253 2073     result = globus_resource_find(id, resource);
254 2073     if(result != GLOBUS_SUCCESS)
255     {
256 1         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
257             result, "No resource found in resource registry");
258         goto exit;
259     }
260
261  exit:
262
263 2073     if(id)
264     {
265 2073         free(id);
266     }
267     
268 2073     GlobusWSRFCoreToolsDebugExit();
269 2073     return result;
270 }
271
272 globus_result_t
273 globus_wsrf_core_get_resource_from_epr(
274     wsa_EndpointReferenceType *         epr,
275     globus_resource_t *                 resource)
276 0 {
277 0     xmlURIPtr                           uri = NULL;
278 0     xmlChar *                           base_path = NULL;
279 0     char *                              service_module_path = NULL;
280 0     globus_extension_handle_t           ext;
281 0     globus_service_descriptor_t *       service = NULL;
282 0     char *                              id = NULL;
283 0     globus_result_t                     result = GLOBUS_SUCCESS;
284 0     GlobusFuncName(globus_wsrf_core_get_resource_from_epr);
285 0     GlobusWSRFCoreToolsDebugEnter();
286     
287 0     globus_assert(epr);
288 0     globus_assert(epr->Address.base_value);
289
290 0     uri = xmlParseURI(epr->Address.base_value);
291 0     if(!uri)
292     {
293 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
294             GLOBUS_SUCCESS, "Failed to parse EPR Address");
295 0         goto exit;
296     }
297
298 0     base_path = uri->path;
299 0     while(*base_path == '/')
300     {
301 0         base_path++;
302     }
303
304 0     service_module_path = globus_common_create_string(
305             GLOBUS_SERVICE_ENGINE_MODULE_PATH_PREFIX "/%s",
306             base_path);
307
308 0     if (service_module_path == NULL)
309     {
310 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
311             GLOBUS_SUCCESS, "Failed to parse EPR Address");
312 0         goto exit;
313     }
314
315 0     service = globus_extension_lookup(
316         &ext, GLOBUS_SERVICE_REGISTRY, service_module_path); 
317 0     if(!service)
318     {
319 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
320             result, "Failed to get service descriptor from EPR Address");
321 0         goto exit;
322     }
323
324 0     result = service->get_resource_id(&epr->ReferenceProperties->any, &id);
325 0     if(result != GLOBUS_SUCCESS)
326     {
327 0         globus_extension_release(ext);
328 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
329             result, "Failed to get resource id from ReferenceProperties");
330 0         goto exit;
331     }
332
333 0     globus_extension_release(ext);
334
335 0     result = globus_resource_find(id, resource);
336 0     if(result != GLOBUS_SUCCESS)
337     {
338 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
339             result, "No resource found in resource registry");
340         goto exit;
341     }
342
343  exit:    
344 0     if(service_module_path)
345     {
346 0         globus_libc_free(service_module_path);
347     }
348
349 0     if(uri)
350     {
351 0         xmlFreeURI(uri);
352     }
353
354 0     if(id)
355     {
356 0         free(id);
357     }
358
359 0     GlobusWSRFCoreToolsDebugExit();
360 0     return result;
361 }
362
363 char *
364 globus_wsrf_core_export_timestamp(
365     xsd_dateTime *                      val)
366 0 {
367 0     return globus_common_create_string(
368         "%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ", 
369             val->tm_year + 1900,
370             val->tm_mon + 1,
371             val->tm_mday,
372             val->tm_hour,
373             val->tm_min,
374             val->tm_sec);
375 }
376
377 #include "libxml/xmlschemastypes.h"
378
379 xsd_dateTime *
380 globus_wsrf_core_import_timestamp(
381     const char *                        timestamp_string)
382 0 {
383 0     xsd_dateTime *                      val = NULL;
384 0     xmlSchemaValPtr                     schema_val = NULL;
385 0     xmlChar *                           tmp_value = NULL;
386 0     int                                 res = 0;
387
388 0     xsd_dateTime_init(&val);
389
390 0     res = xmlSchemaValidatePredefinedType(
391         xmlSchemaGetBuiltInType(XML_SCHEMAS_DATETIME),
392         tmp_value,
393         &schema_val);
394 0     if(res != 0)
395     {
396 0         xsd_dateTime_destroy(val);
397 0         return NULL;
398     }
399
400 0     val->tm_year = schema_val->value.date.year - 1900;
401 0     val->tm_mon = schema_val->value.date.mon;
402 0     val->tm_mday = schema_val->value.date.day;
403 0     val->tm_hour = schema_val->value.date.hour;
404 0     val->tm_min = schema_val->value.date.min;
405 0     val->tm_sec = schema_val->value.date.sec;
406 0     if(schema_val->value.date.tz_flag)
407     {
408 0         val->tm_min += schema_val->value.date.tzo;
409     }
410
411 0     xmlSchemaFreeValue(schema_val);
412
413 0     return val;
414 }
415
416 static
417 globus_object_t *
418 globus_l_error_fault_multiple(
419     const wsbf_BaseFaultType_array *    fault_array)
420 0 {
421 0     globus_object_t *                   error;
422 0     int                                 i;
423     
424 0     error = globus_error_construct_multiple(NULL, 0, "");
425     
426 0     for(i = 0; i < fault_array->length; i++)
427     {
428 0         globus_error_mutliple_add_chain(
429             error,
430             globus_error_convert_wsrf_fault(&fault_array->elements[i]),
431             "");
432     }
433     
434 0     return error;
435 }
436
437 globus_object_t *
438 globus_error_convert_wsrf_fault(
439     const wsbf_BaseFaultType *          fault)
440 0 {
441 0     globus_object_t *                   cause;
442 0     char *                              description = NULL;
443 0     char **                             array;
444     
445 0     if(fault->FaultCause.length == 0)
446     {
447 0         cause = NULL;
448     }
449 0     else if(fault->FaultCause.length == 1)
450     {
451 0         cause = globus_error_convert_wsrf_fault(&fault->FaultCause.elements[0]);
452     }
453     else
454     {
455 0         cause = globus_l_error_fault_multiple(&fault->FaultCause);
456     }
457     
458 0     array = (char **) globus_malloc(
459         sizeof(char *) * fault->Description.length * 2);
460 0     if(array)
461     {
462 0         int                             i;
463 0         int                             j = 0;
464         
465 0         for(i = 0; i < fault->Description.length; i++)
466         {
467 0             if(i > 0)
468             {
469 0                 array[j++] = "\n";
470             }
471 0             array[j++] = fault->Description.elements[i].base_value;
472         }
473         
474 0         description = globus_libc_join((const char **)array, j);
475 0         globus_free(array);
476     }
477     
478 0     return globus_error_construct_string(NULL, cause, "%s", description);
479 }
480
481 static xsd_QName                               generic_epr =
482 {
483     WSA_ENDPOINTREFERENCETYPE_NS,
484     "EndpointReference"
485 };
486
487 globus_result_t
488 globus_wsrf_core_export_endpoint_reference(
489     const wsa_EndpointReferenceType *   endpoint_reference,
490     const char *                        filename,
491     xsd_QName *                         element)
492 0 {
493 0     globus_result_t                     result = GLOBUS_SUCCESS;
494 0     xsd_QName *                         elem = element;
495 0     GlobusFuncName(globus_wsrf_core_export_endpoint_reference);
496 0     GlobusWSRFCoreToolsDebugEnter();
497     
498 0     if(!elem)
499     {
500 0         elem = &generic_epr;
501     }
502
503 0     GlobusXSDTypeExport(filename, 
504                         wsa_EndpointReferenceType,
505                         endpoint_reference,
506                         elem,
507                         result);
508
509 0     if(result != GLOBUS_SUCCESS)
510     {
511 0         result = GlobusWSRFCoreToolsErrorExportFailed(result, filename);
512     }
513
514 0     GlobusWSRFCoreToolsDebugExit();
515 0     return result;
516 }
517
518 globus_result_t
519 globus_wsrf_core_import_endpoint_reference(
520     const char *                        filename,
521     wsa_EndpointReferenceType **        endpoint_reference,
522     xsd_QName *                         element)
523 0 {
524 0     globus_result_t                     result = GLOBUS_SUCCESS;
525 0     GlobusFuncName(globus_wsrf_core_import_endpoint_reference);
526 0     GlobusWSRFCoreToolsDebugEnter();
527     
528 0     wsa_EndpointReferenceType_init(endpoint_reference);
529
530 0     GlobusXSDTypeImport(filename,
531                         wsa_EndpointReferenceType,
532                         (*endpoint_reference),
533                         element,
534                         result);
535 0     if(result != GLOBUS_SUCCESS)
536     {
537 0         result = GlobusWSRFCoreToolsErrorImportFailed(result, filename);
538     }
539
540 0     GlobusWSRFCoreToolsDebugExit();
541 0     return result;