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 #include "globus_service_engine.h"
18 #include "globus_service_registry.h"
19 #include "globus_wsrf_core_tools.h"
20 #include "globus_i_wsrf_core_tools.h"
21 #include "version.h"
22 #include "libxml/uri.h"
23 #include "globus_wsrf_resource.h"
24 #include "globus_error_string.h"
25 #include "wsbf_DescriptionType.h"
26 #include "globus_ws_addressing.h"
27 #include "globus_xsd_primitives.h"
28 #include "globus_wsrf_core_tools.h"
29
30 /**
31  * @mainpage Globus WSRF Core Tools
32  * 
33  * The Globus WSRF Core Tools package consists of C libraries and programs for
34  * accessing and manipulating WSRF resources. The library consists of functions for
35  * manipulating EndpointReferences, performing conversions on some core wsrf
36  * and xml types, and for parsing some standard command-line options for WSRF
37  * client programs.
38  *
39  * This module uses standard Globus module activation and deactivation.
40  *
41  * Before any functions in this module can be called, the GLOBUS_WSRF_CORE_TOOLS_MODULE
42  * module descriptor must be activated.
43  *
44  * <code>
45  * globus_module_activate(GLOBUS_WSRF_CORE_TOOLS_MODULE);
46  * </code>
47  *
48  * This function returns GLOBUS_SUCCESS if the module was
49  * successfully initialized, and you are therefore allowed to call 
50  * functions implemented in it. Otherwise, an error code is returned, and 
51  * functions from this module should not be subsequently called. This function
52  * may be called multiple times.
53  * 
54  * To deactivate this module, the following must be called:
55  *
56  * <code>
57  * globus_module_deactivate(GLOBUS_WSRF_CORE_TOOLS_MODULE);
58  * </code>
59  *
60  * This function should be called once for each time the module was activated. 
61  */
62
63 /**
64  * @defgroup globus_wsrf_core_epr EndpointReferenceType Manipulation
65  * EndpointReferenceType constructors and manipulators.
66  */
67 static int
68 globus_l_wsrf_core_tools_activate();
69
70 static int
71 globus_l_wsrf_core_tools_deactivate();
72
73 globus_module_descriptor_t              globus_l_wsrf_core_tools_module =
74 {
75     "globus_wsrf_core_tools_module",
76     globus_l_wsrf_core_tools_activate,
77     globus_l_wsrf_core_tools_deactivate,
78     NULL,
79     NULL,
80     &local_version
81 };
82
83 0 GlobusDebugDefine(GLOBUS_WSRF_CORE_TOOLS);
84
85 static int
86 globus_l_wsrf_core_tools_activate()
87 {
88 25     int                                 rc = 0;
89 25     GlobusFuncName(globus_l_wsrf_core_tools_activate);
90
91 25     rc = globus_module_activate(GLOBUS_COMMON_MODULE);
92 25     if(rc != GLOBUS_SUCCESS)
93     {
94 0         goto error_exit;
95     }
96
97 25     GlobusDebugInit(GLOBUS_WSRF_CORE_TOOLS, DEBUG INFO TRACE WARN ERROR);
98 25     GlobusWSRFCoreToolsDebugEnter();
99
100 25     rc = globus_module_activate(GLOBUS_SOAP_MESSAGE_MODULE);
101 25     if(rc != GLOBUS_SUCCESS)
102     {
103 0         goto deactivate_common_exit;
104     }
105 25     rc = globus_module_activate(GLOBUS_SERVICE_ENGINE_MODULE);
106 25     if (rc != GLOBUS_SUCCESS)
107     {
108 0         goto deactivate_message_exit;
109     }
110
111 25     if (rc != GLOBUS_SUCCESS)
112     {
113 deactivate_message_exit:
114 0         globus_module_deactivate(GLOBUS_SOAP_MESSAGE_MODULE);
115 deactivate_common_exit:
116 0         globus_module_deactivate(GLOBUS_COMMON_MODULE);
117 error_exit:
118 0         GlobusWSRFCoreToolsDebugExit();
119 0         GlobusDebugDestroy(GLOBUS_WSRF_CORE_TOOLS);
120 0         return rc;
121     }
122
123 25     GlobusWSRFCoreToolsDebugExit();
124 25     return rc;
125 }
126
127 static int
128 globus_l_wsrf_core_tools_deactivate()
129 21 {
130 21     int                                 rc = 0;
131 21     GlobusFuncName(globus_l_wsrf_core_tools_deactivate);
132 21     GlobusWSRFCoreToolsDebugEnter();
133
134 21     rc = globus_module_deactivate(GLOBUS_SOAP_MESSAGE_MODULE);
135 21     if(rc != GLOBUS_SUCCESS)
136     {
137 0         goto exit;
138     }
139 21     globus_module_activate(GLOBUS_SERVICE_ENGINE_MODULE);
140
141
142 21     GlobusWSRFCoreToolsDebugExit();
143 21     GlobusDebugDestroy(GLOBUS_WSRF_CORE_TOOLS);
144 21     globus_module_deactivate(GLOBUS_COMMON_MODULE);
145
146  exit:
147 21     return rc;
148 }
149
150 /**
151  * Construct an EndpointReference.
152  * @ingroup globus_wsrf_core_epr
153  *
154  * Construct an EndpointReference from a collection of information about the
155  * current processing context.
156  * 
157  * @param engine
158  *     An engine which is servicing this resource. The engine is used to determine the
159  *     base part of the address used in the EPR.
160  * @param path
161  *     The service's path which must be passed to the engine when operating on
162  *     this service.
163  * @param resource_id
164  *     The element containing the resource-specific ReferenceProperties. If this
165  *     is non-null, then the any will be moved to the resulting EPR and its original
166  *     values will be destroyed. If this is null, no ReferenceProperties will
167  *     be associated with the EPR.
168  * @param endpoint_reference
169  *     A new EndpointReference which will be populated
170  *
171  * @retval GLOBUS_SUCCESS
172  *     The new endpoint reference was created successfully.
173  * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_NULL_PARAMETER
174  *     Could not create new endpoint reference because @a engine, @a path, or
175  *     @a endpoint_reference was NULL.
176  * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
177  *     Could not create new endpoint reference because of a lack of available memory.
178  */
179 globus_result_t
180 globus_wsrf_core_create_endpoint_reference(
181     globus_service_engine_t             engine,
182     const char *                        path,
183     xsd_any * *                         resource_id,
184     wsa_EndpointReferenceType   *       endpoint_reference)
185 78 {
186 78     globus_result_t                     result = GLOBUS_SUCCESS;
187 78     xsd_any *                           new_rp;
188 78     char *                              contact;
189 78     GlobusFuncName(globus_wsrf_core_create_endpoint_reference);
190 78     GlobusWSRFCoreToolsDebugEnter();
191     
192 78     if (engine == NULL || path == NULL || endpoint_reference == NULL)
193     {
194 0         result = GlobusSoapMessageErrorNullParam;
195
196 0         goto out;
197     }
198 78     result = globus_service_engine_get_contact(engine, &contact);
199 78     if (result != GLOBUS_SUCCESS)
200     {
201 0         goto out;
202     }
203
204 78     result = wsa_EndpointReferenceType_init_contents(endpoint_reference);
205 78     if (result != GLOBUS_SUCCESS)
206     {
207 0         goto free_contact_out;
208     }
209
210 78     endpoint_reference->Address.base_value = 
211             globus_common_create_string("%s%s",
212                                 contact,
213                                 path);
214
215 78     if (endpoint_reference->Address.base_value == NULL)
216     {
217 0         result = GlobusSoapMessageErrorOutOfMemory;
218 0         goto free_contact_out;
219     }
220     
221 78     if (resource_id != NULL)
222     {
223 78         result = wsa_ReferencePropertiesType_init(
224                 &endpoint_reference->ReferenceProperties);
225 78         if (result != GLOBUS_SUCCESS)
226         {
227 0             goto destroy_epr_contents_out;
228         }
229
230 78         new_rp = xsd_any_array_push(&endpoint_reference->ReferenceProperties->any);
231
232 78         if (new_rp == NULL)
233         {
234 0             result = GlobusSoapMessageErrorOutOfMemory;
235 0             goto destroy_epr_contents_out;
236         }
237         
238 78         new_rp->value = (*resource_id)->value;
239 78         new_rp->element = (*resource_id)->element;
240 78         new_rp->any_info = (*resource_id)->any_info;
241
242 78         (*resource_id)->value = NULL;
243 78         (*resource_id)->element = NULL;
244 78         xsd_any_destroy(*resource_id);
245         
246 78         *resource_id = NULL;
247     }
248
249 destroy_epr_contents_out:
250 78     if (result != GLOBUS_SUCCESS)
251     {
252 0         wsa_EndpointReferenceType_destroy_contents(endpoint_reference);
253     }
254 free_contact_out:
255 78     globus_free(contact);
256 out:
257 78     GlobusWSRFCoreToolsDebugExit();
258 78     return result;
259 }
260 /* globus_wsrf_core_create_endpoint_reference() */
261
262 /**
263  * Construct an EndpointReference from a wrapped URI (deprecated)
264  * @ingroup globus_wsrf_core_epr
265  * Construct an EndpointReference from a string in wrapped URI format. The wrapped
266  * URI format is service-contact?reference-property-value (for example
267  * http://localhost:30001/wsrf/services/CounterService?1231231). The name of the reference
268  * property is specified by the @a id_element qname.
269  * 
270  * @param wrapped_uri
271  *     A wrapped-URI string.
272  * @param id_element
273  *     QName of the element to used for the ReferenceProperty contained in the
274  *     @a wrapped_uri. This may be NULL if no reference properties are needed to
275  *     contact the service.
276  * @param endpoint_reference
277  *     A new EndpointReference which will be populated
278  *
279  * @retval GLOBUS_SUCCESS
280  *     The new endpoint reference was created successfully.
281  * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_NULL_PARAMETER
282  *     Could not create new endpoint reference because @a wrapped_uri or
283  *     @a endpoint_reference was NULL.
284  * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
285  *     Could not create new endpoint reference because of a lack of available memory.
286  *
287  * @deprecated 
288  *     The wrapped-URI format used by this function is non-standard.
289  */
290 globus_result_t
291 globus_wsrf_core_unwrap_endpoint_reference(
292     const char *                        wrapped_uri,
293     xsd_QName *                         id_element,
294     wsa_EndpointReferenceType   *       endpoint_reference)
295 0 {
296 0     globus_result_t                     result = GLOBUS_SUCCESS;
297 0     xsd_any *                           new_rp;
298 0     xmlURIPtr                           parsed_uri;
299 0     GlobusFuncName(globus_wsrf_core_unwrap_endpoint_reference);
300 0     GlobusWSRFCoreToolsDebugEnter();
301     
302 0     parsed_uri = xmlParseURI(wrapped_uri);
303     
304 0     wsa_ReferencePropertiesType_init(&endpoint_reference->ReferenceProperties);
305    
306 0     if (parsed_uri->query != NULL && id_element != NULL)
307     {
308 0         new_rp = xsd_any_array_push(&endpoint_reference->ReferenceProperties->any);
309 0         xsd_string_copy_cstr((xsd_string **) &new_rp->value, parsed_uri->query);
310 0         xsd_QName_copy(&new_rp->element, id_element);
311 0         new_rp->any_info = &xsd_string_info;
312
313 0         xmlFree(parsed_uri->query);
314 0         parsed_uri->query = NULL; 
315     }
316 0     endpoint_reference->Address.base_value = (char *) xmlSaveUri(parsed_uri);
317
318 0     xmlFreeURI(parsed_uri);
319
320 0     GlobusWSRFCoreToolsDebugExit();
321 0     return result;
322 }
323
324 /**
325  * Convert an EndpointReference into a wrapped URI (deprecated)
326  * @ingroup globus_wsrf_core_epr
327  * Parse out the address and ReferenceProperties value from an EndpointReference and
328  * put them into a string in wrapped-URI format. The wrapped-URI
329  * format is service-contact?reference-property-value (for example
330  * http://localhost:30001/wsrf/services/CounterService?1231231).
331  * 
332  * @param endpoint_reference
333  *     A new EndpointReference which will be parsed.
334  * @param wrapped_uri
335  *     A pointer to a newly allocated string containing the wrapped-URI.
336  *
337  * @retval GLOBUS_SUCCESS
338  *     The new wrapped_uri was created successfull.
339  * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_NULL_PARAMETER
340  *     Could not create the wrapped URI because @a wrapped_uri or
341  *     @a endpoint_reference was NULL.
342  * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_TYPE_NULL_REF_PROP
343  *     The ReferenceProperties of the EPR were NULL.
344  * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_TYPE_REF_PROP_WRONG_COUNT
345  *     There is not exactly one ReferenceProperties element in the EPR.
346  * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_TYPE_INVALID_REF_PROP
347  *     The reference properties value was not a string type.
348  * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
349  *     Could not create the new wrapped-URI because of a lack of available memory.
350  *
351  * @deprecated 
352  *     The wrapped-URI format used by this function is non-standard.
353  */
354 globus_result_t
355 globus_wsrf_core_wrap_endpoint_reference(
356     const wsa_EndpointReferenceType *   endpoint_reference,
357     char **                             wrapped_uri)
358 0 {
359 0     globus_result_t                     result = GLOBUS_SUCCESS;
360 0     GlobusFuncName(globus_wsrf_core_wrap_endpoint_reference);
361 0     GlobusWSRFCoreToolsDebugEnter();
362
363     /* verify endpoint reference property is xsd_string type */
364 0     if (endpoint_reference == NULL || wrapped_uri == NULL)
365     {
366 0         result = GlobusSoapMessageErrorNullParam;
367
368 0         goto exit;
369     }
370
371 0     if(endpoint_reference->ReferenceProperties)
372     {
373 0         result = GlobusWSRFCoreToolsErrorNullReferenceProperty();
374 0         goto exit;
375     }
376     
377 0     if(endpoint_reference->ReferenceProperties->any.length != 1)
378     {
379 0         result = GlobusWSRFCoreToolsErrorReferencePropertiesWrongCount(
380             endpoint_reference->ReferenceProperties->any.length);
381 0         goto exit;
382     }
383
384 0     if(endpoint_reference->ReferenceProperties->any.elements[0].any_info !=
385        (&xsd_string_info))
386     {
387 0         result = GlobusWSRFCoreToolsErrorInvalidReferenceProperties(
388             endpoint_reference->ReferenceProperties->
389             any.elements[0].any_info->type);
390 0         goto exit;
391     }
392
393 0     *wrapped_uri = globus_common_create_string(
394         "%s?%s",
395         endpoint_reference->Address.base_value,
396         endpoint_reference->ReferenceProperties->any.elements[0].value);
397
398 0     if (*wrapped_uri == NULL)
399     {
400 0         result = GlobusSoapMessageErrorOutOfMemory;
401         goto exit;
402     }
403
404  exit:
405
406 0     GlobusWSRFCoreToolsDebugExit();
407 0     return result;
408 }
409 /* globus_wsrf_core_wrap_endpoint_reference() */
410
411 /**
412  * Obtain a resource handle from a message handle and service descriptor.
413  * @ingroup globus_wsrf_core_resource
414  *
415  * Looks up the resource which is associated with the EndpointReference used in the
416  * addressing headers on the current message.
417  *
418  * @param message
419  *     Message handle which the operation request arrived on.
420  * @param service
421  *     Service handle for the service which is processing the operation.
422  * @param resource
423  *     Pointer to a WSRF resource handle which will be set to the resource
424  *     associated with the SOAP message EPR. This must be released by calling
425  *     globus_resource_finish()
426  *
427  * @retval GLOBUS_SUCCESS
428  *     Resource successfully located.
429  * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
430  *     Unable to locate the resource because of a lack of available memory.
431  * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_TYPE_GET_RESOURCE_FAILED
432  *     Unable to locate the resource because the EPR could not be determined, or the
433  *     resource ID does not map to a valid resource.
434  */
435 globus_result_t
436 globus_wsrf_core_get_resource(
437     globus_soap_message_handle_t        message,
438     globus_service_descriptor_t *       service,
439     globus_resource_t *                 resource)
440 2648 {
441 2648     globus_result_t                     result = GLOBUS_SUCCESS;
442 2648     char *                              id = NULL;
443 2648     wsa_EndpointReferenceType *         epr;
444 2648     GlobusFuncName(globus_wsrf_core_get_resource_id);
445 2648     GlobusWSRFCoreToolsDebugEnter();
446     
447 2648     if (message == NULL || service == NULL || resource == NULL)
448     {
449 0         result = GlobusSoapMessageErrorOutOfMemory;
450 0         goto exit;
451     }
452 2648     epr = globus_soap_message_handle_get_attr(
453         message, 
454         WSADDR_EPR_KEY);
455 2648     if(!epr)
456     {
457 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
458             GLOBUS_SUCCESS, 
459             "No EndpointReference found "
460             "in message properties");
461 0         goto exit;
462     }
463
464 2648     result = service->get_resource_id(&epr->ReferenceProperties->any, &id);
465 2648     if(result != GLOBUS_SUCCESS)
466     {
467 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
468             result, "Failed to get resource id from ReferenceProperties");
469 0         goto exit;
470     }
471
472 2648     result = globus_resource_find(id, resource);
473 2648     if(result != GLOBUS_SUCCESS)
474     {
475 1         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
476             result, "No resource found in resource registry");
477         goto exit;
478     }
479
480  exit:
481
482 2648     if(id)
483     {
484 2648         free(id);
485     }
486     
487 2648     GlobusWSRFCoreToolsDebugExit();
488 2648     return result;
489 }
490 /* globus_wsrf_core_get_resource() */
491
492 /**
493  * Obtain a resource handle from an EPR
494  * @ingroup globus_wsrf_core_resource
495  *
496  * Looks up the resource associated with an EPR.
497  *
498  * @param epr
499  *     Endpoint reference to look up.
500  * @param resource
501  *     Pointer to a WSRF resource handle which will be set to the resource
502  *     associated with the EPR. This must be released by calling
503  *     globus_resource_finish()
504  *
505  * @retval GLOBUS_SUCCESS
506  *     Resource successfully located.
507  * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
508  *     Unable to locate the resource because of a lack of available memory.
509  * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_TYPE_GET_RESOURCE_FAILED
510  *     Unable to locate the resource because the EPR could not be determined, or the
511  *     resource ID does not map to a valid resource.
512  */
513 globus_result_t
514 globus_wsrf_core_get_resource_from_epr(
515     const wsa_EndpointReferenceType *   epr,
516     globus_resource_t *                 resource)
517 140 {
518 140     xmlURIPtr                           uri = NULL;
519 140     char *                              base_path = NULL;
520 140     char *                              service_module_path = NULL;
521 140     globus_extension_handle_t           ext;
522 140     globus_service_descriptor_t *       service = NULL;
523 140     char *                              id = NULL;
524 140     globus_result_t                     result = GLOBUS_SUCCESS;
525 140     GlobusFuncName(globus_wsrf_core_get_resource_from_epr);
526 140     GlobusWSRFCoreToolsDebugEnter();
527     
528 140     if (epr == NULL || resource == NULL)
529     {
530 0         result = GlobusSoapMessageErrorOutOfMemory;
531
532 0         goto exit;
533     }
534
535 140     if (epr->Address.base_value == NULL)
536     {
537 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(GLOBUS_SUCCESS, "Invalid EPR");
538
539 0         goto exit;
540     }
541
542 140     uri = xmlParseURI(epr->Address.base_value);
543 140     if(!uri)
544     {
545 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
546             GLOBUS_SUCCESS, "Failed to parse EPR Address");
547 0         goto exit;
548     }
549
550 140     base_path = (char *) uri->path;
551 295     while(*base_path == '/')
552     {
553 155         base_path++;
554     }
555
556 140     service_module_path = globus_common_create_string(
557             GLOBUS_SERVICE_ENGINE_MODULE_PATH_PREFIX "/%s",
558             base_path);
559 140     if (service_module_path == NULL)
560     {
561 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
562             GLOBUS_SUCCESS, "Failed to parse EPR Address");
563 0         goto exit;
564     }
565 140     GlobusWSRFCoreToolsDebugPrintf(GLOBUS_L_WSRF_CORE_TOOLS_DEBUG_DEBUG,
566             ("Path for service module is `%s'\n", service_module_path));
567
568 140     service = globus_extension_lookup(
569         &ext, GLOBUS_SERVICE_REGISTRY, service_module_path); 
570 140     if(!service)
571     {
572 2         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
573             result, "Failed to get service descriptor from EPR Address");
574 2         goto exit;
575     }
576
577 138     result = service->get_resource_id(&epr->ReferenceProperties->any, &id);
578 138     if(result != GLOBUS_SUCCESS)
579     {
580 0         globus_extension_release(ext);
581 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
582             result, "Failed to get resource id from ReferenceProperties");
583 0         goto exit;
584     }
585
586 138     globus_extension_release(ext);
587
588 138     result = globus_resource_find(id, resource);
589 138     if(result != GLOBUS_SUCCESS)
590     {
591 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
592             result, "No resource found in resource registry");
593         goto exit;
594     }
595
596  exit:    
597 140     if(service_module_path)
598     {
599 140         globus_libc_free(service_module_path);
600     }
601
602 140     if(uri)
603     {
604 140         xmlFreeURI(uri);
605     }
606
607 140     if(id)
608     {
609 138         free(id);
610     }
611
612 140     if (result != GLOBUS_SUCCESS)
613     {
614 2         GlobusWSRFCoreToolsDebugError(result);
615     }
616
617 140     GlobusWSRFCoreToolsDebugExit();
618 140     return result;
619 }
620 /* globus_wsrf_core_get_resource_from_epr() */
621
622 globus_result_t
623 globus_wsrf_core_get_resource_id_from_epr(
624     const wsa_EndpointReferenceType *   epr,
625     char **                             resource_id)
626 376 {
627 376     xmlURIPtr                           uri = NULL;
628 376     char *                              base_path = NULL;
629 376     char *                              service_module_path = NULL;
630 376     globus_extension_handle_t           ext;
631 376     globus_service_descriptor_t *       service = NULL;
632 376     char *                              id = NULL;
633 376     globus_result_t                     result = GLOBUS_SUCCESS;
634 376     GlobusFuncName(globus_wsrf_core_get_resource_from_epr);
635 376     GlobusWSRFCoreToolsDebugEnter();
636     
637 376     globus_assert(epr);
638 376     globus_assert(epr->Address.base_value);
639
640 376     uri = xmlParseURI(epr->Address.base_value);
641 376     if(!uri)
642     {
643 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
644             GLOBUS_SUCCESS, "Failed to parse EPR Address");
645 0         goto exit;
646     }
647
648 376     base_path = (char *) uri->path;
649 782     while(*base_path == '/')
650     {
651 406         base_path++;
652     }
653
654 376     service_module_path = globus_common_create_string(
655             GLOBUS_SERVICE_ENGINE_MODULE_PATH_PREFIX "/%s",
656             base_path);
657
658 376     if (service_module_path == NULL)
659     {
660 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
661             GLOBUS_SUCCESS, "Failed to parse EPR Address");
662 0         goto exit;
663     }
664
665 376     service = globus_extension_lookup(
666         &ext, GLOBUS_SERVICE_REGISTRY, service_module_path); 
667 376     if(!service)
668     {
669 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
670             result, "Failed to get service descriptor from EPR Address");
671 0         goto exit;
672     }
673
674 376     result = service->get_resource_id(&epr->ReferenceProperties->any, &id);
675 376     if(result != GLOBUS_SUCCESS)
676     {
677 0         globus_extension_release(ext);
678 0         result = GlobusWSRFCoreToolsErrorGetResourceFailed(
679             result, "Failed to get resource id from ReferenceProperties");
680 0         goto exit;
681     }
682
683 376     globus_extension_release(ext);
684
685 376     *resource_id = id;
686 376     id = NULL;
687
688  exit:    
689 376     if(service_module_path)
690     {
691 376         globus_libc_free(service_module_path);
692     }
693
694 376     if(uri)
695     {
696 376         xmlFreeURI(uri);
697     }
698
699 376     if(id)
700     {
701 0         free(id);
702     }
703
704 376     GlobusWSRFCoreToolsDebugExit();
705 376     return result;
706 }
707 /* globus_wsrf_core_get_resource_id_from_epr() */
708
709 char *
710 globus_wsrf_core_export_timestamp(
711     xsd_dateTime *                      val)
712 0 {
713 0     return globus_common_create_string(
714         "%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ", 
715             val->tm_year + 1900,
716             val->tm_mon + 1,
717             val->tm_mday,
718             val->tm_hour,
719             val->tm_min,
720             val->tm_sec);
721 }
722
723 #include "libxml/xmlschemastypes.h"
724
725 xsd_dateTime *
726 globus_wsrf_core_import_timestamp(
727     const char *                        timestamp_string)
728 0 {
729 0     xsd_dateTime *                      val = NULL;
730 0     xmlSchemaValPtr                     schema_val = NULL;
731 0     xmlChar *                           tmp_value = NULL;
732 0     int                                 res = 0;
733
734 0     xsd_dateTime_init(&val);
735
736 0     res = xmlSchemaValidatePredefinedType(
737         xmlSchemaGetBuiltInType(XML_SCHEMAS_DATETIME),
738         tmp_value,
739         &schema_val);
740 0     if(res != 0)
741     {
742 0         xsd_dateTime_destroy(val);
743 0         return NULL;
744     }
745
746 0     val->tm_year = schema_val->value.date.year - 1900;
747 0     val->tm_mon = schema_val->value.date.mon;
748 0     val->tm_mday = schema_val->value.date.day;
749 0     val->tm_hour = schema_val->value.date.hour;
750 0     val->tm_min = schema_val->value.date.min;
751 0     val->tm_sec = schema_val->value.date.sec;
752 0     if(schema_val->value.date.tz_flag)
753     {
754 0         val->tm_min += schema_val->value.date.tzo;
755     }
756
757 0     xmlSchemaFreeValue(schema_val);
758
759 0     return val;
760 }
761
762 static
763 globus_object_t *
764 globus_l_error_fault_multiple(
765     const wsbf_BaseFaultType_array *    fault_array)
766 0 {
767 0     globus_object_t *                   error;
768 0     int                                 i;
769     
770 0     error = globus_error_construct_multiple(NULL, 0, "");
771     
772 0     for(i = 0; i < fault_array->length; i++)
773     {
774 0         globus_error_mutliple_add_chain(
775             error,
776             globus_error_convert_wsrf_fault(&fault_array->elements[i]),
777             "");
778     }
779     
780 0     return error;
781 }
782
783 globus_object_t *
784 globus_error_convert_wsrf_fault(
785     const wsbf_BaseFaultType *          fault)
786 0 {
787 0     globus_object_t *                   cause;
788 0     char *                              description = NULL;
789 0     char **                             array;
790     
791 0     if(fault->FaultCause.length == 0)
792     {
793 0         cause = NULL;
794     }
795 0     else if(fault->FaultCause.length == 1)
796     {
797 0         cause = globus_error_convert_wsrf_fault(&fault->FaultCause.elements[0]);
798     }
799     else
800     {
801 0         cause = globus_l_error_fault_multiple(&fault->FaultCause);
802     }
803     
804 0     array = (char **) globus_malloc(
805         sizeof(char *) * fault->Description.length * 2);
806 0     if(array)
807     {
808 0         int                             i;
809 0         int                             j = 0;
810         
811 0         for(i = 0; i < fault->Description.length; i++)
812         {
813 0             if(i > 0)
814             {
815 0                 array[j++] = "\n";
816             }
817 0             array[j++] = fault->Description.elements[i].base_value;
818         }
819         
820 0         description = globus_libc_join((const char **)array, j);
821 0         globus_free(array);
822     }
823     
824 0     return globus_error_construct_string(NULL, cause, "%s", description);
825 }
826
827 static xsd_QName                               generic_epr =
828 {
829     WSA_ENDPOINTREFERENCETYPE_NS,
830     "EndpointReference"
831 };
832
833 globus_result_t
834 globus_wsrf_core_export_endpoint_reference(
835     const wsa_EndpointReferenceType *   endpoint_reference,
836     const char *                        filename,
837     xsd_QName *                         element)
838 0 {
839 0     globus_result_t                     result = GLOBUS_SUCCESS;
840 0     xsd_QName *                         elem = element;
841 0     GlobusFuncName(globus_wsrf_core_export_endpoint_reference);
842 0     GlobusWSRFCoreToolsDebugEnter();
843     
844 0     if(!elem)
845     {
846 0         elem = &generic_epr;
847     }
848
849 0     GlobusXSDTypeExport(filename, 
850                         wsa_EndpointReferenceType,
851                         endpoint_reference,
852                         elem,
853                         result);
854
855 0     if(result != GLOBUS_SUCCESS)
856     {
857 0         result = GlobusWSRFCoreToolsErrorExportFailed(result, filename);
858     }
859
860 0     GlobusWSRFCoreToolsDebugExit();
861 0     return result;
862 }
863
864 globus_result_t
865 globus_wsrf_core_import_endpoint_reference(
866     const char *                        filename,
867     wsa_EndpointReferenceType **        endpoint_reference,
868     xsd_QName *                         element)
869 0 {
870 0     globus_result_t                     result = GLOBUS_SUCCESS;
871 0     GlobusFuncName(globus_wsrf_core_import_endpoint_reference);
872 0     GlobusWSRFCoreToolsDebugEnter();
873     
874 0     wsa_EndpointReferenceType_init(endpoint_reference);
875
876 0     GlobusXSDTypeImport(filename,
877                         wsa_EndpointReferenceType,
878                         (*endpoint_reference),
879                         element,
880                         result);
881 0     if(result != GLOBUS_SUCCESS)
882     {
883 0         result = GlobusWSRFCoreToolsErrorImportFailed(result, filename);
884     }
885
886 0     GlobusWSRFCoreToolsDebugExit();
887 0     return result;