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 #include "globus_soap_message.h"
13 #include "globus_wsrf_resource.h"
14 #include "globus_service_engine.h"
15 #include "globus_operation_provider.h"
16 #include "globus_service_registry.h"
17 #include "globus_wsrf_core_tools.h"
18
19 #include "xsd_dateTime.h"
20
21 #include "wsrl_SetTerminationTimeType.h"
22 #include "wsrl_SetTerminationTimeResponseType.h"
23
24 #include "version.h"
25
26 /*
27 * This define causes the wsrl_i_faults.h to define faults relevant to this
28 * port type.
29 */
30 #define WSRL_SCHEDULED_RESOURCE_TERMINATION 1
31 /* We don't implement any sort of change policy, so we don't use this fault
32 * type.
33 */
34 #define NEED_TERMINATION_TIME_CHANGE_REJECTED_FAULT 0
35
36 #include "wsrl_i_faults.h"
37
38 /**
39 * @page wsrl_ScheduledResourceTermination_provider ScheduledResourceTermination Provider
40 *
41 * <h2>Provider Usage Overview</h2>
42 * This operation provider implements the ScheduledResourceTermination portType
43 * defined in
44 * http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl .
45 * This portType consists of the @a SetTerminationTime operation, @a
46 * TerminationTime and @a CurrentTime resource properties, and
47 * related faults.
48 *
49 * The WSRF service engine will automatically register this provider to handle
50 * the SetTerminationTime operation for services which use the port type.
51 *
52 * <h2>Notes</h2>
53 * - The CurrentTime and TerminationTime resource properties are stored in GMT.
54 *
55 * <h2>Limitations</h2>
56 * - This provider does not implement any policies regarding what is an
57 * acceptable change of the TerminationTime. The
58 * TerminationTimeChangeRejectedFaultType is never issued by this provider.
59 */
60 GlobusExtensionDeclareModule(wsrl_ScheduledResourceTermination);
61
62 /* Prototypes */
63 static
64 globus_result_t
65 wsrl_ScheduledResourceTermination_init_resource(
66 const char * resource_id);
67
68 static
69 globus_result_t
70 wsrl_SetTerminationTime_init_provider(
71 globus_service_engine_t engine,
72 globus_soap_message_handle_t handle,
73 wsrl_SetTerminationTimeType * SetTerminationTime);
74
75 static
76 globus_result_t
77 wsrl_SetTerminationTime_provider(
78 globus_service_engine_t engine,
79 globus_soap_message_handle_t handle,
80 globus_service_descriptor_t * service,
81 wsrl_SetTerminationTimeType * SetTerminationTime,
82 wsrl_SetTerminationTimeResponseType *
83 SetTerminationTimeResponse,
84 char ** fault_name,
85 void ** fault);
86
87 static
88 void
89 wsrl_CurrentTime_callback(
90 void * arg,
91 const xsd_QName * qname,
92 void ** property);
93
94 static
95 time_t
96 wsrl_l_timegm(
97 const struct tm * tm);
98
99 static
100 int
101 wsrl_ScheduledResourceTermination_activate(void);
102
103 static
104 int
105 wsrl_ScheduledResourceTermination_deactivate(void);
106
107 /* Local Variables */
108 static xsd_QName wsrl_SetTerminationTime_qname =
109 {
110 "http://www.globus.org/docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl",
111 "SetTerminationTime"
112 };
113
114 static xsd_QName wsrl_CurrentTime_qname =
115 {
116 "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.xsd",
117 "CurrentTime"
118 };
119
120 static xsd_QName wsrl_TerminationTime_qname =
121 {
122 "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.xsd",
123 "TerminationTime"
124 };
125
126 static
127 globus_operation_provider_descriptor_t
128 wsrl_SetTerminationTime_descriptor =
129 {
130 &wsrl_SetTerminationTime_qname,
131 "SetTerminationTime",
132 (void *)wsrl_SetTerminationTime_init_provider,
133 (void *)wsrl_SetTerminationTime_provider,
134 wsrl_ScheduledResourceTermination_init_resource
135 };
136
137 GlobusExtensionDefineModule(wsrl_ScheduledResourceTermination) =
138 {
139 "wsrl_ScheduledResourceTermination",
140 wsrl_ScheduledResourceTermination_activate,
141 wsrl_ScheduledResourceTermination_deactivate,
142 NULL,
143 NULL,
144 &local_version
145 };
146
147 /* Implementation */
148 static
149 globus_result_t
150 wsrl_ScheduledResourceTermination_init_resource(
151 const char * resource_id)
152 24 {
153 globus_resource_t resource;
154 globus_result_t result;
155
156 24 result = globus_resource_find(resource_id, &resource);
157
158 24 if (result != GLOBUS_SUCCESS)
159 {
160 24 goto out;
161 }
162
163 24 result = globus_resource_create_property(
164 resource,
165 &wsrl_TerminationTime_qname,
166 &xsd_dateTime_info,
167 NULL);
168
169 24 if (result != GLOBUS_SUCCESS)
170 {
171 24 goto finish_out;
172 }
173
174 24 result = globus_resource_create_property_callback(
175 resource,
176 &wsrl_CurrentTime_qname,
177 &xsd_dateTime_info,
178 wsrl_CurrentTime_callback,
179 NULL);
180
181 24 finish_out:
182 24 globus_resource_finish(resource);
183 24 out:
184 24 return result;
185 }
186 /* wsrl_ScheduledResourceTermination_init_resource() */
187
188
189 static
190 globus_result_t
191 wsrl_SetTerminationTime_init_provider(
192 globus_service_engine_t engine,
193 globus_soap_message_handle_t handle,
194 wsrl_SetTerminationTimeType * SetTerminationTime)
195 15 {
196 /* NOOP */
197 15 return GLOBUS_SUCCESS;
198 }
199
200 static
201 globus_result_t
202 wsrl_SetTerminationTime_provider(
203 globus_service_engine_t engine,
204 globus_soap_message_handle_t handle,
205 globus_service_descriptor_t * service,
206 wsrl_SetTerminationTimeType * SetTerminationTime,
207 wsrl_SetTerminationTimeResponseType *
208 SetTerminationTimeResponse,
209 char ** fault_name,
210 void ** fault)
211 15 {
212 globus_result_t result;
213 globus_resource_t resource;
214 globus_abstime_t termination_time;
215 time_t now;
216 xsd_dateTime * termination_time_rp;
217
218 15 result = globus_wsrf_core_get_resource(handle, service, &resource);
219
220 15 if (result != GLOBUS_SUCCESS || resource == NULL)
221 {
222 0 result = wsrl_l_ResourceUnknownFaultType_create(
223 fault_name,
224 (wsrl_ResourceUnknownFaultType **) fault);
225
226 0 goto out;
227 }
228
229 15 termination_time.tv_sec = wsrl_l_timegm(
230 &SetTerminationTime->RequestedTerminationTime);
231
232 15 termination_time.tv_nsec = 0;
233
234 15 result = globus_resource_set_destroy_time(resource, &termination_time);
235
236 15 if (result != GLOBUS_SUCCESS)
237 {
238 0 result = wsrl_l_UnableToSetTerminationTimeFaultType_create(
239 fault_name,
240 (wsrl_UnableToSetTerminationTimeFaultType **) fault);
241
242
243 0 goto finish_out;
244 }
245
246 15 now = time(NULL);
247
248 15 memcpy(&SetTerminationTimeResponse->NewTerminationTime,
249 &SetTerminationTime->RequestedTerminationTime,
250 sizeof(xsd_dateTime));
251
252 15 globus_libc_gmtime_r(&now, &SetTerminationTimeResponse->CurrentTime);
253
254 15 xsd_dateTime_init(&termination_time_rp);
255
256 15 memcpy(termination_time_rp,
257 &SetTerminationTime->RequestedTerminationTime,
258 sizeof(xsd_dateTime));
259
260 15 result = globus_resource_set_property(
261 resource,
262 &wsrl_TerminationTime_qname,
263 termination_time_rp);
264
265 15 if (result != GLOBUS_SUCCESS)
266 {
267 15 goto finish_out;
268 }
269
270 15 result = globus_resource_finish(resource);
271
272 15 if (result != GLOBUS_SUCCESS)
273 {
274 15 goto out;
275 }
276 15 return GLOBUS_SUCCESS;
277
278 0 finish_out:
279 0 globus_resource_finish(resource);
280 0 out:
281 0 return result;
282 }
283 /* wsrl_SetTerminationTime_provider() */
284
285
286 static
287 void
288 wsrl_CurrentTime_callback(
289 void * arg,
290 const xsd_QName * qname,
291 void ** property)
292 1 {
293 time_t now_time;
294 xsd_dateTime * now;
295
296 1 globus_assert(
297 strcmp(qname->Namespace,
298 wsrl_CurrentTime_qname.Namespace) == 0);
299 1 globus_assert(
300 strcmp(qname->local,
301 wsrl_CurrentTime_qname.local) == 0);
302
303 1 now_time = time(NULL);
304
305 1 xsd_dateTime_init((xsd_dateTime **) property);
306 1 now = *property;
307
308 1 globus_libc_gmtime_r(&now_time, now);
309
310 return;
311 }
312 /* wsrl_CurrentTime_callback() */
313
314 /**
315 * Convert a struct tm to a time_t without accounting for the local timezone
316 * or modifying the struct tm contents.
317 *
318 * This may get a little kooky when the TZ shift occurs near the DST change.
319 */
320 static
321 time_t
322 wsrl_l_timegm(
323 const struct tm * tm)
324 15 {
325 struct tm tmp;
326 struct tm local_tm;
327 time_t local_time;
328 time_t shifted_time;
329
330 15 memcpy(&tmp, tm, sizeof(struct tm));
331
332 /* convert the tm to time_t in the local timezone */
333 15 local_time = mktime(&tmp);
334
335 /* create a new tm with this time (but without the TZ-related parts of the
336 * tm set) */
337 15 globus_libc_gmtime_r(&local_time, &local_tm);
338
339 /* convert the time to local time again, causing it to be shifted by
340 * time zone twice
341 */
342 15 shifted_time = mktime(&local_tm);
343
344 /*
345 * The difference between shifted_time and local_time is the TZ correction.
346 */
347 15 return local_time + (local_time - shifted_time);
348
349 /*
350 * This snippet is based on the timegm manpage, but is not thread safe
351 *
352 * tz = globus_libc_getenv("TZ");
353 * setenv("TZ", "", 1);
354 * tzset();
355 * termination_time.tv_sec = mktime(
356 * &SetTerminationTime->RequestedTerminationTime);
357 * if (tz != NULL)
358 * {
359 * globus_libc_setenv("TZ", tz, 1);
360 * }
361 * else
362 * {
363 * globus_libc_unsetenv("TZ");
364 * }
365 * tzset();
366 */
367 }
368 /* wsrl_l_timegm() */
369
370 static
371 int
372 wsrl_ScheduledResourceTermination_activate(void)
373 28 {
374 28 int res = 0;
375 GlobusFuncName(wsrl_ScheduledResourceTermination_activate);
376
377 28 res = globus_extension_registry_add(
378 GLOBUS_OPERATION_PROVIDER_REGISTRY,
379 &wsrl_SetTerminationTime_qname,
380 GlobusExtensionMyModule(wsrl_ScheduledResourceTermination),
381 &wsrl_SetTerminationTime_descriptor);
382
383 28 return res;
384 }
385 /* wsrl_ScheduledResourceTermination_activate() */
386
387 static
388 int
389 wsrl_ScheduledResourceTermination_deactivate(void)
390 0 {
391 GlobusFuncName(wsrl_ScheduledResourceTermination_deactivate);
392
393 0 globus_extension_registry_remove(
394 GLOBUS_OPERATION_PROVIDER_REGISTRY,
395 &wsrl_SetTerminationTime_qname);
396
397 0 return 0;
398 }