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_i_wsrf_service_group.h"
18 #include "wssg_Content.h"
19
20 /**
21  * Get a list of entries associated with a service group
22  * @ingroup wssg
23  * Returns a list of the entries associated with the service group named 
24  * by @a service_group_epr in the array pointed to by @a entries. 
25  *
26  * @param service_group_epr
27  *     EPR containing a reference to the service group.
28  * @param entries
29  *     List of entries which will be populated with the current list
30  *     of entries and their values.
31  *
32  * @retval GLOBUS_SUCCESS
33  * @retval #GLOBUS_SERVICE_GROUP_ERROR_TYPE_NULL_PARAMETER
34  * @retval #GLOBUS_SERVICE_GROUP_ERROR_TYPE_OUT_OF_MEMORY
35  * @retval #GLOBUS_SERVICE_GROUP_ERROR_TYPE_UNKNOWN
36  */
37 globus_result_t
38 globus_service_group_get_entries(
39     const wsa_EndpointReferenceType *   service_group_epr,
40     wssg_EntryType_array *              entries)
41 8 {
42 8     globus_wsrf_service_group_t         sg;
43 8     globus_wsrf_service_group_entry_t   sge;
44 8     globus_result_t                     result;
45 8     wssg_EntryType *                    tmp;
46 8     globus_resource_t                   resource;
47 8     xsd_anyType *                       tmp_content = NULL;
48 8     int                                 i;
49 8     GlobusFuncName(globus_service_group_get_entries);
50
51 8     GlobusServiceGroupDebugEnter();
52 8     if (service_group_epr == NULL || entries == NULL)
53     {
54 2         result = GLOBUS_SERVICE_GROUP_NULL_PARAMETER();
55         
56 2         goto out;
57     }
58 6     result = wssg_EntryType_array_init_contents(entries);
59 6     if (result != GLOBUS_SUCCESS)
60     {
61 0         result = GLOBUS_SERVICE_GROUP_OUT_OF_MEMORY();
62
63 0         goto out;
64     }
65
66 6     result = globus_i_service_group_lookup(
67             service_group_epr,
68             &sg);
69
70 6     if (result != GLOBUS_SUCCESS)
71     {
72 1         goto destroy_entries_out;
73     }
74
75 5     sge = globus_hashtable_first(
76             &sg->entries);
77
78     /* Extract a list of Entry structs from the hashtable owned by
79      * the service group. The entry resources must be accessed and released
80      * outside of the SG lock.
81      */
82 15     while (sge != NULL)
83     {
84 10         tmp = wssg_EntryType_array_push(entries);
85 10         if (tmp == NULL)
86         {
87 0             result = GLOBUS_SERVICE_GROUP_OUT_OF_MEMORY();
88
89 0             goto unlock_out;
90         }
91
92 10         result = wssg_EntryType_copy_contents(
93                 tmp, 
94                 sge->entry);
95
96 10         if (result != GLOBUS_SUCCESS)
97         {
98 0             result = GLOBUS_SERVICE_GROUP_OUT_OF_MEMORY();
99
100 0             goto unlock_out;
101         }
102 10         sge = globus_hashtable_next(&sg->entries);
103     }
104 5     GlobusServiceGroupUnlock(sg);
105
106 15     for (i = 0; i < entries->length; i++)
107     {
108         /* The only copy of the content is in the entry's resource property,
109          * so we extract that into the array value
110          */
111 10         result = globus_wsrf_core_get_resource_from_epr(
112                 entries->elements[i].ServiceGroupEntryEPR,
113                 &resource);
114
115 10         if (result != GLOBUS_SUCCESS &&
116                 globus_error_match(
117                     globus_error_peek(result),
118                     GLOBUS_WSRF_RESOURCE_MODULE,
119                     GLOBUS_WSRF_RESOURCE_ERROR_TYPE_UNKNOWN_RESOURCE))
120         {
121             /* This entry was destroyed while we were accessing the list. */
122 0             memmove(&entries->elements[i],
123                     &entries->elements[i+1],
124                     sizeof(wssg_EntryType) * (entries->length - i));
125
126             /* Retry with the next from the list */
127 0             entries->length--;
128 0             i--;
129
130 0             continue;
131         }
132 10         else if (result != GLOBUS_SUCCESS)
133         {
134             /* Something baadd */
135 0             result = GLOBUS_SERVICE_GROUP_OUT_OF_MEMORY();
136
137 0             goto destroy_entries_out;
138         }
139
140 10         result = globus_resource_get_property(
141                     resource,
142                     &wssg_Content_qname,
143                     (void **) &tmp_content,
144                     NULL);
145 10         if (result != GLOBUS_SUCCESS)
146         {
147 0             result = GLOBUS_SERVICE_GROUP_UNKNOWN();
148
149 0             globus_resource_finish(resource);
150
151 0             goto destroy_entries_out;
152         }
153
154 10         result = xsd_anyType_copy(
155                 &entries->elements[i].Content,
156                 tmp_content);
157 10         if (result != GLOBUS_SUCCESS)
158         {
159 0             result = GLOBUS_SERVICE_GROUP_OUT_OF_MEMORY();
160
161 0             globus_resource_finish(resource);
162
163 0             goto destroy_entries_out;
164         }
165
166 10         globus_resource_finish(resource);
167     }
168
169 5     if (result != GLOBUS_SUCCESS)
170     {
171 unlock_out:
172 0         GlobusServiceGroupUnlock(sg);
173 destroy_entries_out:
174 1         wssg_EntryType_array_destroy_contents(entries);
175     }
176
177 out:
178 8     GlobusServiceGroupDebugExit();
179 8     return result;
180 }