Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_service.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Service Support
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 
17 
18 typedef struct {
19  const afw_pool_t * p;
20  afw_object_cb_t original_callback;
21  void *original_context;
22  const afw_query_criteria_t * criteria;
23  apr_hash_t *service_ids;
24  const afw_object_t *last_object;
26 
27 
28 typedef struct {
29  /* Returned object for get. */
30  const afw_object_t *object;
31 
32  /* This is a manual start. */
33  afw_boolean_t manual_start;
35 
36 
37 static const afw_value_string_t
38 impl_startup_values[] =
39 {
40 
41 #define XX(id, _) \
42  { \
43  &afw_value_evaluated_string_inf, \
44  AFW_UTF8_LITERAL(# id) \
45  },
47 #undef XX
48  {
50  AFW_UTF8_LITERAL("invalid"),
51  }
52 
53 };
54 
55 
56 
57 #define impl_startup_value(id) \
58 (const afw_value_t *)&impl_startup_values[afw_service_startup_ ## id]
59 
60 
61 
62 static const afw_value_string_t impl_startup_descriptions[] =
63 {
64 #define XX(id, desc) \
65  { \
66  &afw_value_evaluated_string_inf, \
67  AFW_UTF8_LITERAL(desc) \
68  },
70 #undef XX
71  {
73  AFW_UTF8_LITERAL("invalid"),
74  }
75 };
76 
77 
78 
79 static const afw_value_string_t
80 impl_status_values[] =
81 {
82 #define XX(id, _) \
83  { \
84  &afw_value_evaluated_string_inf, \
85  AFW_UTF8_LITERAL(# id) \
86  },
88 #undef XX
89  {
91  AFW_UTF8_LITERAL("invalid"),
92  }
93 };
94 
95 
96 
97 #define impl_status_value(id) \
98 (const afw_value_t *)&impl_status_values[afw_service_status_ ## id]
99 
100 
101 static const afw_value_string_t
102 impl_status_descriptions[] =
103 {
104 
105 #define XX(id, desc) \
106  { \
107  &afw_value_evaluated_string_inf, \
108  AFW_UTF8_LITERAL(desc) \
109  },
111 #undef XX
112  {
114  AFW_UTF8_LITERAL("invalid"),
115  }
116 };
117 
118 
119 /* Internal start a service. */
120 static void
121 impl_start_service(
122  afw_service_t *service,
123  afw_xctx_t *xctx);
124 
125 
126 /* Internal restart a service. */
127 static void
128 impl_restart_service(
129  afw_service_t *service,
130  afw_xctx_t *xctx);
131 
132 
133 /* Convert afw_service_startup_t enum to corresponding utf8. */
134 AFW_DEFINE(const afw_utf8_t *)
136 {
138 
139  i = startup;
140  if (i < 0 || i >= afw_service_startup_invalid) {
141  i = afw_service_startup_invalid;
142  }
143 
144  return &impl_startup_values[i].internal;
145 }
146 
147 
148 /* Convert afw_service_startup_t enum to corresponding adaptive value. */
149 AFW_DEFINE(const afw_value_t *)
151 {
153 
154  i = startup;
155  if (i < 0 || i >= afw_service_startup_invalid) {
156  i = afw_service_startup_invalid;
157  }
158 
159  return (const afw_value_t *)&impl_startup_values[i];
160 }
161 
162 
163 /* Get description for a afw_service_startup_t enum. */
164 AFW_DEFINE(const afw_utf8_t *)
166 {
168 
169  i = startup;
170  if (i < 0 || i >= afw_service_startup_invalid) {
171  i = afw_service_startup_invalid;
172  }
173 
174  return &impl_startup_descriptions[i].internal;
175 }
176 
177 
178 /* Get description as value for a afw_service_startup_t enum. */
179 AFW_DEFINE(const afw_value_t *)
181 {
183 
184  i = startup;
185  if (i < 0 || i >= afw_service_startup_invalid) {
186  i = afw_service_startup_invalid;
187  }
188 
189  return (const afw_value_t*)&impl_startup_descriptions[i];
190 }
191 
192 
193 /* Convert utf8 to corresponding afw_service_startup_t enum. */
196 {
197  afw_service_startup_t result;
198 
199  for (result = 0;
200  result < afw_service_startup_invalid &&
201  !afw_utf8_equal(&impl_startup_values[result].internal, s);
202  result++);
203 
204  return result;
205 }
206 
207 
208 /* Convert afw_service_status_t enum to corresponding utf8. */
209 AFW_DEFINE(const afw_utf8_t *)
211 {
213 
214  i = status;
215  if (i < 0 || i >= afw_service_status_invalid) {
216  i = afw_service_status_invalid;
217  }
218 
219  return &impl_status_values[i].internal;
220 }
221 
222 
223 /* Convert afw_service_status_t enum to corresponding adaptive value. */
224 AFW_DEFINE(const afw_value_t *)
226 {
228 
229  i = status;
230  if (i < 0 || i >= afw_service_status_invalid) {
231  i = afw_service_status_invalid;
232  }
233 
234  return (const afw_value_t *)&impl_status_values[i];
235 }
236 
237 
238 /* Get description of a afw_service_status_t enum. */
239 AFW_DECLARE(const afw_utf8_t *)
241 {
243 
244  i = status;
245  if (i < 0 || i >= afw_service_status_invalid) {
246  i = afw_service_status_invalid;
247  }
248 
249  return &impl_status_descriptions[i].internal;
250 }
251 
252 
253 /* Get description as value of a afw_service_status_t enum. */
254 AFW_DECLARE(const afw_value_t *)
256 {
258 
259  i = status;
260  if (i < 0 || i >= afw_service_status_invalid) {
261  i = afw_service_status_invalid;
262  }
263 
264  return (const afw_value_t *)&impl_status_descriptions[i];
265 }
266 
267 
268 /* Convert utf8 to corresponding afw_service_status_t enum. */
271 {
272  afw_service_status_t result;
273 
274  for (result = 0;
275  result < afw_service_status_invalid &&
276  !afw_utf8_equal(&impl_status_values[result].internal, s);
277  result++);
278 
279  return result;
280 }
281 
282 
283 
284 static void
285 impl_initialize_and_start_service_using_conf(
286  afw_service_t *service,
287  const afw_utf8_t *source_location,
288  afw_boolean_t restart,
289  const afw_object_t *conf,
290  const afw_utf8_t *conf_source_location,
291  afw_xctx_t *xctx)
292 {
293  apr_status_t rv;
294  const afw_utf8_t *s;
295  const afw_pool_t *p = service->p;
296  const afw_utf8_t *object_id;
297 
298  /* properties and source_location */
299  service->properties = afw_object_create_clone(conf, p, xctx);;
300  service->source_location = source_location;
301  service->conf_source_location = conf_source_location;
302 
303  /* Set sourceLocation in properties. */
305  &afw_s_sourceLocation, conf_source_location, xctx);
306  /* type */
308  service->properties,
309  &afw_s_type, xctx);
310  if (!service->type || service->type->len == 0) {
311  AFW_THROW_ERROR_FZ(general, xctx,
313  "missing conf/type property",
314  AFW_UTF8_FMT_ARG(conf_source_location));
315  }
316 
317  /* service type */
319  service->type, xctx);
320  if (!service->service_type) {
321  AFW_THROW_ERROR_FZ(general, xctx,
323  "invalid service type %" AFW_UTF8_FMT,
324  AFW_UTF8_FMT_ARG(source_location),
325  AFW_UTF8_FMT_ARG(service->type));
326  }
327 
328  /* conf subtype */
329  service->conf_subtype = NULL;
330  if (service->service_type->conf_type->subtype_property_name) {
332  service->properties,
333  service->service_type->conf_type->subtype_property_name, xctx);
334  if (!service->conf_subtype || service->conf_subtype->len == 0)
335  {
336  AFW_THROW_ERROR_FZ(general, xctx,
338  "missing conf/%" AFW_UTF8_FMT " property",
339  AFW_UTF8_FMT_ARG(source_location),
340  AFW_UTF8_FMT_ARG(service->service_type->conf_type->
341  subtype_property_name));
342  }
343  }
344 
345  /* conf id */
346  service->conf_id = NULL;
347  if (service->service_type->conf_type->id_property_name)
348  {
350  service->properties,
351  service->service_type->conf_type->id_property_name, xctx);
352  if (!service->conf_id || service->conf_id->len == 0)
353  {
354  AFW_THROW_ERROR_FZ(general, xctx,
356  "missing %" AFW_UTF8_FMT " property",
357  AFW_UTF8_FMT_ARG(conf_source_location),
358  AFW_UTF8_FMT_ARG(service->service_type->conf_type->id_property_name)
359  );
360  }
361  }
362 
363  /* service id */
364  object_id = (service->conf_id) ? service->conf_id : &afw_s_current;
365  s = afw_utf8_printf(p, xctx,
366  "%" AFW_UTF8_FMT
367  "-%" AFW_UTF8_FMT,
368  AFW_UTF8_FMT_ARG(service->type),
369  AFW_UTF8_FMT_ARG(object_id));
370  if (service->service_id.len > 0) {
371  if (!afw_utf8_equal(&service->service_id, s)) {
372  AFW_THROW_ERROR_FZ(general, xctx,
374  "serviceId %" AFW_UTF8_FMT
375  " is not appropriate for this conf",
376  AFW_UTF8_FMT_ARG(source_location),
377  AFW_UTF8_FMT_ARG(s));
378  }
379  }
380  service->service_id.len = s->len;
381  service->service_id.s = s->s;
382 
383  /* conf objectType */
384  s = afw_utf8_printf(p, xctx,
385  "_AdaptiveConf_%" AFW_UTF8_FMT
386  "%s%" AFW_UTF8_FMT,
387  AFW_UTF8_FMT_ARG(service->type),
388  (service->conf_subtype) ? "_" : "",
389  (service->conf_subtype) ? (int)service->conf_subtype->len : 0,
390  (service->conf_subtype) ? service->conf_subtype->s : NULL);
392 
393  rv = apr_thread_mutex_create(
394  &service->mutex,
395  APR_THREAD_MUTEX_UNNESTED, afw_pool_get_apr_pool(p));
396  if (rv != APR_SUCCESS) {
397  AFW_THROW_ERROR_RV_Z(general, apr, rv,
398  "apr_thread_mutex_create() failed", xctx);
399  }
400 
401  service->status = afw_service_status_ready_to_start;
402  if (restart) {
403  impl_restart_service(service, xctx);
404  }
405  else {
406  impl_start_service(service, xctx);
407  }
408 }
409 
410 
411 
412 /* Retrieve _AdaptiveServiceConf_ objects start initial callback. */
413 static afw_boolean_t
414 impl_start_cb(
415  const afw_object_t *object,
416  void *context,
417  afw_xctx_t *xctx)
418 {
419  impl_start_context_t *ctx = context;
420  const afw_pool_t *p;
421  const afw_utf8_t *service_id;
422  const afw_utf8_t *startup;
423  afw_service_t *service;
424  afw_service_t *old_service;
425  const afw_object_t *conf;
426  const afw_utf8_t *source_location;
427 
428  /* If no object, return. */
429  if (!object) return false;
430  p = NULL;
431  source_location = afw_object_meta_get_path(object, xctx);
432 
433  service = NULL;
434  service_id = &afw_s_unknown;
435  AFW_TRY {
436 
437  /*
438  * Return if startup is not immediate or permanent, except when this
439  * is a manual start and startup is manual.
440  */
441  startup = afw_object_old_get_property_as_string(object,
442  &afw_s_startup, xctx);
443  if (
444  !startup ||
445  (!afw_utf8_equal(startup, &afw_s_immediate) &&
446  !afw_utf8_equal(startup, &afw_s_permanent) &&
447  !(ctx->manual_start && afw_utf8_equal(startup, &afw_s_manual)))
448  )
449  {
450  break; /* Return. */
451  }
452 
453  /* Get serviceId. Default to object id. */
454  service_id = afw_object_old_get_property_as_string(object,
455  &afw_s_serviceId, xctx);
456  if (!service_id) {
457  service_id = afw_object_meta_get_object_id(object, xctx);
458  }
459  if (!service_id) {
460  AFW_THROW_ERROR_FZ(general, xctx,
462  "serviceId can not be determined",
463  AFW_UTF8_FMT_ARG(source_location));
464  }
465 
466  /*
467  * See if service already registered. Return if anything except error
468  * or a manual start and service stopped.
469  */
470  service = afw_environment_get_service(service_id, xctx);
471  if (service &&
472  service->status != afw_service_status_error &&
473  !(ctx->manual_start &&
474  service->status == afw_service_status_stopped)
475  )
476  {
477  break; /* Return. */
478  }
479 
480  /* Allocate and initialize new service instance. */
481  old_service = service;
482  p = afw_pool_create_multithreaded(xctx->env->p, xctx);
483  service = afw_pool_calloc_type(p, afw_service_t, xctx);
484  service->p = p;
485  service->source_location = afw_utf8_clone(source_location,
486  p, xctx);
487  source_location = service->source_location;
488  service->service_id.len = service_id->len;
489  service->service_id.s = afw_memory_dup(
490  service_id->s, service_id->len, p, xctx);
491  service->has_service_conf = true;
492  if (!old_service) {
493  afw_environment_register_service(&service->service_id, service,
494  xctx);
495  }
496 
498  &afw_s_conf, xctx);
499  if (!conf) {
500  AFW_THROW_ERROR_FZ(general, xctx,
502  "missing conf property",
503  AFW_UTF8_FMT_ARG(source_location));
504  }
505  conf = afw_object_create_clone(conf, p, xctx);
507  p, xctx, "%" AFW_UTF8_FMT "/conf",
508  AFW_UTF8_FMT_ARG(source_location));
509 
510  /* Start service and release existing service if there is one. */
511  impl_initialize_and_start_service_using_conf(service,
512  source_location, false, conf, service->conf_source_location, xctx);
513  }
514 
519  if (service) {
520  service->status = afw_service_status_error;
522  AFW_ERROR_THROWN->message_z, AFW_UTF8_Z_LEN,
523  p, xctx);
524  service->status_debug = afw_error_to_utf8(
525  AFW_ERROR_THROWN, p, xctx);
526  }
528  AFW_LOG_FZ(err, xctx, "Service %" AFW_UTF8_FMT " failed to start.",
529  AFW_UTF8_FMT_ARG(service_id));
530 
532  }
533 
534  AFW_FINALLY{
536  }
537 
538  AFW_ENDTRY;
539 
540  /* Return indicating not to short circuit */
541  return false;
542 }
543 
544 
545 
546 /* Start initial services */
547 void
548 afw_service_internal_start_initial_services(
549  const afw_pool_t *p, afw_xctx_t *xctx)
550 {
551  const afw_adaptor_session_t *session;
553 
554  /* Clear ctx and set p. */
555  afw_memory_clear(&ctx);
556 
557  /* If there is not a conf adaptor, nothing to start, so return. */
558  if (!xctx->env->conf_adaptor ||
559  xctx->env->conf_adaptor->adaptor_id.len == 0)
560  {
561  return;
562  }
563 
564  /* Start immediate and permanent services. */
565  session = afw_adaptor_session_create(
566  &xctx->env->conf_adaptor->adaptor_id, xctx);
567  AFW_TRY {
569  &afw_s__AdaptiveServiceConf_, NULL,
570  &ctx, impl_start_cb, NULL, p, xctx);
571  }
572 
573  AFW_FINALLY{
574  afw_adaptor_session_release(session, xctx);
575  }
576 
577  AFW_ENDTRY;
578 }
579 
580 
581 
582 static void
583 impl_add_runtime_service_info_to_object(
584  const afw_object_t *object,
585  const afw_service_t *service,
586  const afw_object_t *service_conf,
587  const afw_object_t *conf_property,
588  const afw_utf8_t *service_id,
589  const afw_utf8_t *type,
590  const afw_utf8_t *id,
591  afw_xctx_t *xctx)
592 {
593  const afw_pool_t *p = object->p;
594  const afw_service_type_t *service_type;
595  const afw_utf8_t *subtype;
596  const afw_utf8_t *conf_object_type_id;
597  const afw_value_t *value;
598  const afw_value_t *value_description;
599  const afw_value_t *startup_value;
600  afw_service_startup_t startup;
601  const afw_utf8_t *s;
602  const afw_utf8_octet_t *c;
603  afw_size_t len;
604  afw_utf8_t w_type;
605  afw_utf8_t w_id;
606  afw_boolean_t can_start = false;
607  afw_boolean_t can_stop = false;
608  afw_boolean_t can_restart = false;
609 
611  &afw_s_afw, &afw_s__AdaptiveService_, service_id, xctx);
612 
613  /* If type or id is NULL, determine from service_id. */
614  if (!type || !id) {
615  c = service_id->s;
616  len = service_id->len;
617  for (
618  w_type.s = c = service_id->s,
619  w_type.len = len = service_id->len;
620  len > 0 && *c != '-';
621  c++, len--
622  );
623  if (len > 0) {
624  w_type.len = c - w_type.s;
625  w_id.s = c + 1;
626  w_id.len = len - 1;
627  }
628  if (len <= 0 || w_id.len < 1) {
629  AFW_THROW_ERROR_FZ(general, xctx,
630  "Invalid serviceId %" AFW_UTF8_FMT,
631  AFW_UTF8_FMT_ARG(service_id));
632  }
633  type = &w_type;
634  id = &w_id;
635  }
636 
637  service_type = afw_environment_get_service_type(type, xctx);
638  if (!service_type) {
639  AFW_THROW_ERROR_FZ(general, xctx,
640  "Invalid type in serviceId %" AFW_UTF8_FMT,
641  AFW_UTF8_FMT_ARG(service_id));
642  }
643 
645  &afw_s_serviceId, service_id, xctx);
647  &afw_s_serviceType, type, xctx);
649  &afw_s_confId, id, xctx);
650 
651  subtype = NULL;
652  if (service_type->conf_type->subtype_property_name) {
653  subtype = afw_object_old_get_property_as_string(conf_property,
654  service_type->conf_type->subtype_property_name, xctx);
655  if (!subtype) {
656  AFW_THROW_ERROR_FZ(general, xctx,
657  "missing conf/%" AFW_UTF8_FMT
658  " property in serviceId %" AFW_UTF8_FMT,
660  service_type->conf_type->subtype_property_name),
661  AFW_UTF8_FMT_ARG(service_id));
662  }
664  &afw_s_confSubtype, subtype, xctx);
665  }
666 
667  if (service_type->conf_type->id_runtime_object_type_id) {
668  s = afw_utf8_printf(p, xctx,
669  "/afw/%" AFW_UTF8_FMT
670  "/%" AFW_UTF8_FMT,
671  AFW_UTF8_FMT_ARG(service_type->conf_type->
672  id_runtime_object_type_id),
673  AFW_UTF8_FMT_ARG(id));
675  &afw_s_uriRelated, s, xctx);
676  }
677 
678  if (subtype) {
679  conf_object_type_id = afw_utf8_printf(p, xctx,
680  "_AdaptiveConf_%" AFW_UTF8_FMT
681  ".%" AFW_UTF8_FMT,
682  AFW_UTF8_FMT_ARG(type), AFW_UTF8_FMT_ARG(subtype));
683 
684  } else {
685  conf_object_type_id = afw_utf8_printf(p, xctx,
686  "_AdaptiveConf_%" AFW_UTF8_FMT,
687  AFW_UTF8_FMT_ARG(type));
688  }
689 
691  &afw_s_confPropertyObjectType, conf_object_type_id, xctx);
692 
693  startup = afw_service_startup_invalid;
694  if (service_conf) {
695  startup_value = afw_object_get_property(service_conf, &afw_s_startup,
696  xctx);
697  if (afw_value_is_string(startup_value)) {
698  startup = afw_service_startup_as_enum(
699  &((const afw_value_string_t *)startup_value)->internal);
700  }
701  /* permanent not allowed in conf. */
702  if (startup == afw_service_startup_permanent) {
703  startup = afw_service_startup_invalid;
704  }
705  afw_object_set_property(object, &afw_s_startup,
706  (const afw_value_t *)&impl_startup_values[startup], xctx);
707  afw_object_set_property(object, &afw_s_startupDescription,
708  (const afw_value_t *)&impl_startup_descriptions[startup], xctx);
709 
710  if (startup == afw_service_startup_manual ||
711  startup == afw_service_startup_immediate)
712  {
713  if (service) {
714  switch (service->status) {
715 
716  case afw_service_status_error:
717  case afw_service_status_ready_to_start:
718  case afw_service_status_stopped:
719  can_start = true;
720  break;
721 
722  case afw_service_status_running:
723  can_restart = true;
724  can_stop = true;
725 
726  case afw_service_status_disabled:
727  case afw_service_status_starting:
728  case afw_service_status_stopping:
729  case afw_service_status_restarting:
731  break;
732 
733  case afw_service_status_invalid:
734  default:
735  AFW_THROW_ERROR_Z(code, "Invalid case", xctx);
736  }
737  }
738  else {
739  can_start = true;
740  }
741  }
742  }
743  else {
744  afw_object_set_property(object, &afw_s_startup,
745  (const afw_value_t *)
746  &impl_startup_values[afw_service_startup_permanent], xctx);
747  afw_object_set_property(object, &afw_s_startupDescription,
748  (const afw_value_t *)
749  &impl_startup_descriptions[afw_service_startup_permanent], xctx);
750  }
751 
752  if (service) {
753 
754  /*
755  * If there is a service entry that use to have a service conf and it
756  * is running, allow it to be stopped.
757  */
758  if (service->has_service_conf && !service_conf &&
759  service->status == afw_service_status_running)
760  {
761  can_stop = true;
762  }
763 
765  &afw_s_status,
767  xctx);
768 
770  &afw_s_statusDescription,
772  xctx);
773 
774  if (service->source_location && service->source_location->len > 0) {
776  &afw_s_sourceLocation, service->source_location, xctx);
777  }
778 
780  &afw_s_startTime, &service->start_time, xctx);
781 
782 
783  if (service->status_message && service->status_message->len > 0) {
785  &afw_s_statusMessage, service->status_message, xctx);
786  }
787 
788  if (service->status_debug && service->status_debug->len > 0) {
790  &afw_s_statusDebug, service->status_debug, xctx);
791  }
792 
793  }
794 
795  else {
796  if (startup == afw_service_startup_disabled)
797  {
798  value = (const afw_value_t *)
799  &impl_status_values[afw_service_status_disabled];
800  value_description = (const afw_value_t *)
801  &impl_status_descriptions[afw_service_status_disabled];
802  } else {
803  value = (const afw_value_t *)
804  &impl_status_values[afw_service_status_ready_to_start];
805  value_description = (const afw_value_t *)
806  &impl_status_descriptions[afw_service_status_ready_to_start];
807  }
808  afw_object_set_property(object, &afw_s_status, value, xctx);
809  afw_object_set_property(object, &afw_s_statusDescription,
810  value_description, xctx);
811  }
812 
814  &afw_s_canStart, can_start, xctx);
816  &afw_s_canStop, can_stop, xctx);
818  &afw_s_canRestart, can_restart, xctx);
819 }
820 
821 
822 
823 /*
824  * _AdaptiveService_ get/retrieve cb. Augments _AdaptiveServiceConf_ object
825  * with runtime info then calls original callback.
826  */
827 static afw_boolean_t
828 impl_AdaptiveService_cb(
829  const afw_object_t *original_object,
830  void *context,
831  afw_xctx_t *xctx)
832 {
833  impl_AdaptiveService_context_t *ctx = context;
834  const afw_utf8_t *service_id;
835  const afw_service_t *service;
836  afw_boolean_t meetsCriteria;
837  const afw_pool_t *p;
838  const afw_object_t *conf_property;
839  const afw_object_t *object;
840  const afw_utf8_t *s;
841  const afw_value_t *value;
842  const afw_utf8_t *error_message;
843  afw_boolean_t is_complete;
844 
845  is_complete = false;
846  p = xctx->p;
847  object = original_object;
848  if (object) {
849  service_id = &afw_s_unknown; /* Get rid of compiler warning. */
850  AFW_TRY {
851 
852  p = original_object->p;
853 
854  object = afw_object_create(p, xctx);
855 
857  original_object,
858  &afw_s_serviceId, xctx);
859  if (!service_id) {
860  AFW_THROW_ERROR_Z(general, "missing serviceId", xctx);
861  }
862 
863  s = afw_object_meta_get_path(original_object, xctx);
865  &afw_s_uriServiceConf, s, xctx);
867  &afw_s_sourceLocation, s, xctx);
868 
869  value = afw_object_get_property(original_object,
870  &afw_s_annotation, xctx);
871  if (value) {
872  afw_object_set_property(object, &afw_s_annotation, value,
873  xctx);
874  }
875 
877  original_object, &afw_s_conf, xctx);
878  if (!conf_property) {
879  AFW_THROW_ERROR_FZ(general, xctx,
880  "missing conf property in serviceId %" AFW_UTF8_FMT,
881  AFW_UTF8_FMT_ARG(service_id));
882  }
883 
884  service = afw_environment_get_service(service_id, xctx);
885  impl_add_runtime_service_info_to_object(object, service,
886  original_object, conf_property, service_id,
887  NULL, NULL, xctx);
888 
889  }
890 
892  error_message = afw_utf8_create_copy(
893  AFW_ERROR_THROWN->message_z, AFW_UTF8_Z_LEN,
894  p, xctx);
896  &afw_s_statusMessage,
897  error_message, xctx);
898  error_message = afw_error_to_utf8(AFW_ERROR_THROWN,
899  p, xctx);
901  &afw_s_statusDebug,
902  error_message, xctx);
903  afw_object_set_property(object, &afw_s_startup,
904  impl_startup_value(disabled), xctx);
905  afw_object_set_property(object, &afw_s_status,
906  impl_status_value(error), xctx);
907  }
908 
909  AFW_ENDTRY;
910 
911  meetsCriteria = true;
912  if (ctx->criteria) {
913  meetsCriteria = afw_query_criteria_test_object(object,
914  ctx->criteria, ctx->p, xctx);
915  }
916 
917  if (ctx->service_ids) {
918  apr_hash_set(ctx->service_ids, service_id->s, service_id->len,
919  service_id);
920  }
921 
922  if (meetsCriteria && ctx->original_callback) {
923  is_complete = ctx->original_callback(object,
924  ctx->original_context, xctx);
925  }
926  }
927 
928  ctx->last_object = object;
929 
930  /* Return indicating not to short circuit */
931  return is_complete;
932 }
933 
934 
935 static afw_boolean_t
936 impl_retrieve_from_registry_cb(
937  int type_number,
938  void *data,
939  const afw_utf8_octet_t *key_s,
940  afw_size_t key_len,
941  void *value,
942  const afw_pool_t *p,
943  afw_xctx_t *xctx)
944 {
945  const afw_service_t *service = value;
946  impl_AdaptiveService_context_t *ctx = data;
947  const afw_object_t *object;
948  afw_boolean_t meetsCriteria;
949  afw_boolean_t is_complete;
950 
951  is_complete = false;
952  if (!ctx->service_ids || !apr_hash_get(ctx->service_ids, key_s, key_len)) {
953  object = afw_object_create_managed(p, xctx);
954 
955  impl_add_runtime_service_info_to_object(object, service,
956  NULL, service->properties, &service->service_id,
957  service->type, service->conf_id, xctx);
958 
959  meetsCriteria = true;
960  if (ctx->criteria) {
961  meetsCriteria = afw_query_criteria_test_object(object,
962  ctx->criteria, p, xctx);
963  }
964 
965  if (meetsCriteria && ctx->original_callback) {
966  is_complete = ctx->original_callback(object, ctx->original_context,
967  xctx);
968  }
969  }
970 
971  return is_complete;
972 }
973 
974 
975 
976 /* Special routine for _AdaptiveService_ session retrieve_objects(). */
977 void
978 afw_service_internal_AdaptiveService_retrieve_objects (
979  const afw_adaptor_session_t * instance,
980  const afw_adaptor_impl_request_t * impl_request,
981  const afw_utf8_t * object_type_id,
982  const afw_query_criteria_t * criteria,
983  void * context,
984  afw_object_cb_t callback,
985  const afw_object_t *adaptor_type_specific,
986  const afw_pool_t * p,
987  afw_xctx_t *xctx)
988 {
990  const afw_adaptor_session_t *session;
991 
992  memset(&ctx, 0, sizeof(ctx));
993  ctx.p = p;
994  ctx.original_callback = callback;
995  ctx.original_context = context;
996  ctx.criteria = criteria;
997 
998  if (xctx->env->conf_adaptor) {
999  session = afw_adaptor_session_create(
1000  &xctx->env->conf_adaptor->adaptor_id, xctx);
1001  AFW_TRY {
1002  ctx.service_ids = apr_hash_make(afw_pool_get_apr_pool(p));
1004  session, NULL, &afw_s__AdaptiveServiceConf_,
1005  NULL /* Callback checks criteria. */,
1006  &ctx, impl_AdaptiveService_cb,
1007  NULL, p, xctx);
1008  }
1009 
1010  AFW_FINALLY {
1011  afw_adaptor_session_release(session, xctx);
1012  }
1013 
1014  AFW_ENDTRY;
1015 
1016  }
1017 
1018  /* Add any that are registered but not in service conf. */
1020  afw_environemnt_registry_type_service,
1021  impl_retrieve_from_registry_cb,
1022  &ctx,
1023  p, xctx);
1024 
1025 
1026  /* Call with a NULL object. */
1027  callback(NULL, context, xctx);
1028 }
1029 
1030 
1031 
1032 /* Special routine for _AdaptiveService_ session get_object(). */
1033 void
1034 afw_service_internal_AdaptiveService_get_object (
1035  const afw_adaptor_session_t * instance,
1036  const afw_adaptor_impl_request_t * impl_request,
1037  const afw_utf8_t * object_type_id,
1038  const afw_utf8_t * object_id,
1039  void * context,
1040  afw_object_cb_t callback,
1041  const afw_object_t *adaptor_type_specific,
1042  const afw_pool_t * p,
1043  afw_xctx_t *xctx)
1044 {
1045 
1046  const afw_object_t *result;
1047 
1048  /* Get result. */
1049  result = afw_service_get_object(object_id, p, xctx);
1050 
1051  /* Callback with result. */
1052  callback(result, context, xctx);
1053 }
1054 
1055 
1057 AFW_DECLARE(const afw_object_t *)
1059  const afw_utf8_t *service_id,
1060  const afw_pool_t *p,
1061  afw_xctx_t *xctx)
1062 {
1064  const afw_adaptor_session_t *session;
1065  const afw_object_t *result = NULL;
1066  const afw_service_t *service;
1067  const afw_utf8_t *error_message;
1068 
1069  result = NULL;
1070  memset(&ctx, 0, sizeof(ctx));
1071  ctx.p = p;
1072 
1073  /* Get service. */
1074  service = afw_environment_get_service(service_id, xctx);
1075 
1076  /*
1077  * If no service yet or is existing service that has a service conf, try
1078  * getting object via services conf adaptor.
1079  */
1080  if ((!service || service->has_service_conf) && xctx->env->conf_adaptor)
1081  {
1082  session = afw_adaptor_session_create(
1083  &xctx->env->conf_adaptor->adaptor_id, xctx);
1084  AFW_TRY {
1086  session, NULL, &afw_s__AdaptiveServiceConf_, service_id,
1087  &ctx, impl_AdaptiveService_cb,
1088  NULL, p, xctx);
1089  result = ctx.last_object;
1090  }
1091 
1092  AFW_CATCH(not_found) {
1093  /* Okay, result is NULL. */
1094  }
1095 
1097  result = ctx.last_object;
1098  if (!result) {
1099  result = afw_object_create(p, xctx);
1100  }
1102  &afw_s_serviceId, service_id, xctx);
1103 
1104  error_message = afw_utf8_create_copy(
1105  AFW_ERROR_THROWN->message_z, AFW_UTF8_Z_LEN,
1106  p, xctx);
1108  &afw_s_statusMessage, error_message, xctx);
1109 
1110  error_message = afw_error_to_utf8(AFW_ERROR_THROWN,
1111  p, xctx);
1113  &afw_s_statusDebug, error_message, xctx);
1114 
1115  afw_object_set_property(result, &afw_s_startup,
1116  impl_startup_value(disabled), xctx);
1117  afw_object_set_property(result, &afw_s_status,
1118  impl_status_value(error), xctx);
1119  }
1120 
1121  AFW_FINALLY {
1122  afw_adaptor_session_release(session, xctx);
1123  }
1124 
1125  AFW_ENDTRY;
1126  }
1127 
1128 
1129  /* If not available in services conf, return result based on registered service. */
1130  if (!result) {
1131  if (service) {
1132  result = afw_object_create_managed(p, xctx);
1133  impl_add_runtime_service_info_to_object(result,
1134  service, NULL, service->properties,
1135  service_id, service->type, service->conf_id,
1136  xctx);
1137  }
1138  }
1139 
1140  return result;
1141 }
1142 
1143 
1144 
1145 /* Start a service. */
1146 AFW_DEFINE(void)
1148  const afw_object_t *conf,
1149  const afw_utf8_t *source_location,
1150  const afw_pool_t *p, afw_xctx_t *xctx)
1151 {
1152  afw_service_t *service;
1153 
1154  /* Allocate service struct. */
1155  service = afw_pool_calloc_type(p, afw_service_t, xctx);
1156  service->p = p;
1157  service->source_location = &afw_s_conf;
1158  service->conf_source_location = source_location;
1159 
1160  impl_initialize_and_start_service_using_conf(service,
1161  &afw_s_conf, false, conf, source_location, xctx);
1162 }
1163 
1164 
1165 
1166 /* Start a service. */
1167 static void
1168 impl_start_service(
1169  afw_service_t *service,
1170  afw_xctx_t *xctx)
1171 {
1172  const afw_service_t *existing_service;
1173 
1174  AFW_THREAD_MUTEX_LOCK(service->mutex, xctx)
1175  {
1176  afw_dateTime_set_now(&service->start_time, NULL, xctx);
1177  service->status = afw_service_status_starting;
1178  existing_service = afw_environment_get_service(
1179  &service->service_id, xctx);
1180  afw_environment_register_service(&service->service_id, service,
1181  xctx);
1182  AFW_LOG_FZ(debug, xctx, "Service %" AFW_UTF8_FMT " starting.",
1183  AFW_UTF8_FMT_ARG(&service->service_id));
1185  service->properties, service->p, xctx);
1186  service->status = afw_service_status_running;
1187  if (existing_service) {
1189  }
1190  AFW_LOG_FZ(info, xctx, "Service %" AFW_UTF8_FMT
1191  " successfully started.",
1192  AFW_UTF8_FMT_ARG(&service->service_id));
1193  }
1195 }
1196 
1197 
1198 
1199 /* Insure service is started. */
1200 AFW_DEFINE(void)
1202  const afw_utf8_t *service_id,
1203  afw_boolean_t manual_start,
1204  afw_xctx_t *xctx)
1205 {
1206  const afw_service_t *service;
1207  const afw_utf8_t *description;
1208  const afw_adaptor_session_t *session;
1209  const afw_pool_t *p;
1211 
1212  /* Clear ctx and set p. */
1213  afw_memory_clear(&ctx);
1214  ctx.manual_start = manual_start;
1215 
1216  service = afw_environment_get_service(service_id, xctx);
1217 
1218  /* If service already registered, allow error status to retry. */
1219  if (service &&
1220  service->status != afw_service_status_ready_to_start &&
1221  service->status != afw_service_status_stopped &&
1222  service->status != afw_service_status_error)
1223  {
1224  description = afw_service_status_description(service->status);
1225  AFW_THROW_ERROR_FZ(general, xctx,
1226  "Service %" AFW_UTF8_FMT
1227  " can not be started. %" AFW_UTF8_FMT,
1228  AFW_UTF8_FMT_ARG(service_id),
1229  AFW_UTF8_FMT_ARG(description));
1230  }
1231 
1232  /* Should not get this condition, but fuss anyways. */
1233  if (!xctx->env->conf_adaptor) {
1234  AFW_THROW_ERROR_FZ(general, xctx,
1235  "Can not start service %" AFW_UTF8_FMT,
1236  AFW_UTF8_FMT_ARG(service_id));
1237  }
1238 
1239  /* If there is a conf adaptor, try to start. */
1240  session = afw_adaptor_session_create(
1241  &xctx->env->conf_adaptor->adaptor_id, xctx);
1242  AFW_TRY {
1243  p = afw_pool_create(xctx->env->p, xctx);
1244  afw_adaptor_session_get_object(session, NULL,
1245  &afw_s__AdaptiveServiceConf_, service_id,
1246  &ctx, impl_start_cb, NULL, p, xctx);
1247  }
1248 
1250  AFW_LOG_Z(err, AFW_ERROR_THROWN->message_z, xctx);
1252  }
1253 
1254  AFW_FINALLY {
1255  afw_adaptor_session_release(session, xctx);
1256  }
1257  AFW_ENDTRY;
1258 
1259 }
1260 
1261 
1262 
1263 
1264 /* Stop a service. */
1265 AFW_DEFINE(void)
1267  const afw_utf8_t *service_id,
1268  afw_xctx_t *xctx)
1269 {
1270  afw_service_t *service;
1271  const afw_utf8_t *description;
1272 
1273  service = afw_environment_get_service(service_id, xctx);
1274  if (!service) {
1275  AFW_THROW_ERROR_FZ(general, xctx,
1276  "Service %" AFW_UTF8_FMT " is not running",
1277  AFW_UTF8_FMT_ARG(service_id));
1278  }
1279 
1280  AFW_THREAD_MUTEX_LOCK(service->mutex, xctx)
1281  {
1282  if (service->status == afw_service_status_running) {
1283 
1284  AFW_TRY {
1285  service->status = afw_service_status_stopping;
1286  AFW_LOG_FZ(debug, xctx, "Service %" AFW_UTF8_FMT
1287  " stopping.",
1288  AFW_UTF8_FMT_ARG(&service->service_id));
1289  service->status = afw_service_status_stopping;
1291  service->conf_id, xctx);
1292  AFW_LOG_FZ(info, xctx, "Service %" AFW_UTF8_FMT
1293  " successfully stopped.",
1294  AFW_UTF8_FMT_ARG(&service->service_id));
1295  service->status = afw_service_status_stopped;
1296  }
1297 
1299  AFW_LOG_Z(err, AFW_ERROR_THROWN->message_z, xctx);
1300  service->status =
1302  service->service_type, service->conf_id, xctx) > 0)
1303  ? afw_service_status_running
1304  : afw_service_status_stopped;
1306  }
1307 
1308  AFW_ENDTRY;
1309  }
1310  else {
1311  description = afw_service_status_description(service->status);
1312  AFW_THROW_ERROR_FZ(general, xctx,
1313  "Service %" AFW_UTF8_FMT
1314  " can not be stopped. %" AFW_UTF8_FMT,
1315  AFW_UTF8_FMT_ARG(&service->service_id),
1316  AFW_UTF8_FMT_ARG(description));
1317 
1318  }
1319  }
1321 
1322 }
1323 
1324 
1325 
1326 /* Restart a service. */
1327 static void
1328 impl_restart_service(
1329  afw_service_t *service,
1330  afw_xctx_t *xctx)
1331 {
1332  const afw_service_t *existing_service;
1333 
1334  AFW_THREAD_MUTEX_LOCK(service->mutex, xctx)
1335  {
1336  afw_dateTime_set_now(&service->start_time, NULL, xctx);
1337  service->status = afw_service_status_restarting;
1338  existing_service = afw_environment_get_service(
1339  &service->service_id, xctx);
1340  AFW_LOG_FZ(debug, xctx, "Service %" AFW_UTF8_FMT " restarting.",
1341  AFW_UTF8_FMT_ARG(&service->service_id));
1343  service->properties, service->p, xctx);
1344  service->status = afw_service_status_running;
1345  if (existing_service) {
1347  }
1348  AFW_LOG_FZ(info, xctx, "Service %" AFW_UTF8_FMT
1349  " successfully restarted.",
1350  AFW_UTF8_FMT_ARG(&service->service_id));
1351  }
1353 }
1354 
1355 
1356 /* Get _AdaptiveServiceConf_ objects start initial callback. */
1357 static afw_boolean_t
1358 impl_restart_get_cb(
1359  const afw_object_t *object,
1360  void *context,
1361  afw_xctx_t *xctx)
1362 {
1363  impl_start_context_t *ctx = context;
1364  const afw_pool_t *p;
1365  const afw_utf8_t *service_id;
1366  const afw_utf8_t *startup;
1367  afw_service_t *service;
1368  const afw_object_t *conf;
1369  const afw_utf8_t *source_location;
1370 
1371  /* If no object, return. */
1372  ctx->object = object;
1373  if (!object) return false;
1374  p = NULL;
1375  source_location = afw_object_meta_get_path(object, xctx);
1376 
1377  service = NULL;
1378  service_id = &afw_s_unknown;
1379  AFW_TRY {
1380 
1381  /*
1382  * Return if startup is not immediate or permanent, except when this
1383  * is a manual start and startup is manual.
1384  */
1385  startup = afw_object_old_get_property_as_string(object,
1386  &afw_s_startup, xctx);
1387  if (!startup ||
1388  (!afw_utf8_equal(startup, &afw_s_immediate) &&
1389  !afw_utf8_equal(startup, &afw_s_manual)))
1390  {
1391  break; /* Return. */
1392  }
1393 
1394  /* Get serviceId. Default to object id. */
1395  service_id = afw_object_old_get_property_as_string(object,
1396  &afw_s_serviceId, xctx);
1397  if (!service_id) {
1398  service_id = afw_object_meta_get_object_id(object, xctx);
1399  }
1400  if (!service_id) {
1401  AFW_THROW_ERROR_FZ(general, xctx,
1403  "serviceId can not be determined",
1404  AFW_UTF8_FMT_ARG(source_location));
1405  }
1406 
1407  /* Allocate and initialize new service instance. */
1408  p = afw_pool_create_multithreaded(xctx->env->p, xctx);
1409  service = afw_pool_calloc_type(p, afw_service_t, xctx);
1410  service->p = p;
1411  service->source_location = afw_utf8_clone(source_location,
1412  p, xctx);
1413  source_location = service->source_location;
1414  service->service_id.len = service_id->len;
1415  service->service_id.s = afw_memory_dup(
1416  service_id->s, service_id->len, p, xctx);
1417  service->has_service_conf = true;
1418 
1420  p, xctx, "%" AFW_UTF8_FMT "/conf",
1421  AFW_UTF8_FMT_ARG(source_location));
1423  &afw_s_conf, xctx);
1424  if (!conf) {
1425  AFW_THROW_ERROR_FZ(general, xctx,
1427  "missing conf property",
1428  AFW_UTF8_FMT_ARG(source_location));
1429  }
1430 
1431  /* Start service and release existing service if there is one. */
1432  impl_initialize_and_start_service_using_conf(service,
1433  source_location, true, conf, service->conf_source_location, xctx);
1434  }
1435 
1437  if (service) {
1438  service->status = afw_service_status_error;
1440  AFW_ERROR_THROWN->message_z, AFW_UTF8_Z_LEN,
1441  p, xctx);
1442  service->status_debug = afw_error_to_utf8(
1443  AFW_ERROR_THROWN, p, xctx);
1444  }
1446  AFW_LOG_FZ(err, xctx, "Service %" AFW_UTF8_FMT " failed to start.",
1447  AFW_UTF8_FMT_ARG(service_id));
1448 
1450  }
1451 
1452  AFW_FINALLY{
1454  }
1455 
1456  AFW_ENDTRY;
1457 
1458  /* Return indicating not to short circuit */
1459  return false;
1460 }
1461 
1462 
1463 /* Restart a service. */
1464 AFW_DEFINE(void)
1466  const afw_utf8_t *service_id,
1467  afw_xctx_t *xctx)
1468 {
1469  const afw_service_t *service;
1470  const afw_adaptor_session_t *session;
1471  afw_boolean_t error;
1472  const afw_pool_t *p;
1474 
1475  /* Clear ctx and set p. */
1476  afw_memory_clear(&ctx);
1477 
1478  service = afw_environment_get_service(service_id, xctx);
1479 
1480  /* If service already registered, allow error status to retry. */
1481  if (!service || service->status != afw_service_status_running)
1482  {
1483  AFW_THROW_ERROR_FZ(general, xctx,
1484  "Service %" AFW_UTF8_FMT
1485  " cannot be restarted. It is not running",
1486  AFW_UTF8_FMT_ARG(service_id));
1487  }
1488 
1489  /* If there is a conf adaptor, try to start. */
1490  if (!xctx->env->conf_adaptor) {
1491  goto error;
1492  }
1493 
1494  error = false;
1495  session = afw_adaptor_session_create(
1496  &xctx->env->conf_adaptor->adaptor_id, xctx);
1497  AFW_TRY {
1498  p = afw_pool_create(xctx->env->p, xctx);
1499  afw_adaptor_session_get_object(session, NULL,
1500  &afw_s__AdaptiveServiceConf_, service_id,
1501  &ctx, impl_restart_get_cb, NULL, p, xctx);
1502  }
1503 
1505  error = true;
1506  AFW_LOG_Z(err, AFW_ERROR_THROWN->message_z, xctx);
1507  }
1508 
1509  AFW_FINALLY {
1510  afw_adaptor_session_release(session, xctx);
1511  }
1512  AFW_ENDTRY;
1513  if (error) {
1514  goto error;
1515  }
1516  return;
1517 
1518 error:
1519  AFW_THROW_ERROR_FZ(general, xctx,
1520  "Error starting service %" AFW_UTF8_FMT,
1521  AFW_UTF8_FMT_ARG(service_id));
1522 }
AFW_DEFINE(const afw_object_t *)
#define AFW_DECLARE(type)
Declare a public afw function.
Adaptive Framework Core Internal.
#define afw_adaptor_session_retrieve_objects(instance, impl_request, object_type_id, criteria, context, callback, adaptor_type_specific, p, xctx)
Call method retrieve_objects of interface afw_adaptor_session.
#define afw_adaptor_session_get_object(instance, impl_request, object_type_id, object_id, context, callback, adaptor_type_specific, p, xctx)
Call method get_object of interface afw_adaptor_session.
afw_adaptor_session_release(const afw_adaptor_session_t *session, afw_xctx_t *xctx)
Release an adaptor session created by afw_adaptor_session_create().
Definition: afw_adaptor.c:282
afw_adaptor_session_create(const afw_utf8_t *adaptor_id, afw_xctx_t *xctx)
Create an adaptor session.
Definition: afw_adaptor.c:265
afw_object_set_property_as_anyURI(const afw_object_t *object, const afw_utf8_t *property_name, const afw_utf8_t *internal, afw_xctx_t *xctx)
Set property function for data type anyURI values.
afw_object_set_property_as_boolean(const afw_object_t *object, const afw_utf8_t *property_name, afw_boolean_t internal, afw_xctx_t *xctx)
Set property function for data type boolean values.
afw_object_set_property_as_dateTime(const afw_object_t *object, const afw_utf8_t *property_name, const afw_dateTime_t *internal, afw_xctx_t *xctx)
Set property function for data type dateTime values.
#define afw_object_old_get_property_as_object(object, property_name, xctx)
Get property function for data type object value.
#define afw_object_old_get_property_as_string(object, property_name, xctx)
Get property function for data type string value.
afw_value_evaluated_string_inf
Unmanaged evaluated value inf for data type string.
#define afw_value_is_string(A_VALUE)
Macro to determine if value is evaluated string.
afw_object_set_property_as_string(const afw_object_t *object, const afw_utf8_t *property_name, const afw_utf8_t *internal, afw_xctx_t *xctx)
Set property function for data type string values.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
#define AFW_SERVICE_STARTUP_MAP(XX)
Map used for afw_service_startup_t enum.
Definition: afw_common.h:1298
#define AFW_UTF8_Z_LEN
String is NUL (0) terminate.
Definition: afw_common.h:266
afw_boolean_t(* afw_object_cb_t)(const afw_object_t *object, void *context, afw_xctx_t *xctx)
Typedef for afw_adaptor_session_object callback.
Definition: afw_common.h:1176
#define AFW_UTF8_LITERAL(A_STRING)
String literal initializer.
Definition: afw_common.h:582
#define AFW_UTF8_CONTEXTUAL_LABEL_FMT
Format string used for source location.
Definition: afw_common.h:595
_Bool afw_boolean_t
Definition: afw_common.h:373
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
enum afw_service_status_e afw_service_status_t
Typedef for service status enum.
enum afw_service_startup_e afw_service_startup_t
Typedef for service startup type enum.
#define AFW_SERVICE_STATUS_MAP(XX)
Map used for afw_service_status_t enum.
Definition: afw_common.h:1321
char afw_utf8_octet_t
8 bits of utf-8 codepoint.
Definition: afw_common.h:236
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
@ afw_log_priority_err
Definition: afw_common.h:985
void afw_environment_register_service(const afw_utf8_t *service_id, afw_service_t *service, afw_xctx_t *xctx)
Register a service.
const afw_service_type_t * afw_environment_get_service_type(const afw_utf8_t *service_type_id, afw_xctx_t *xctx)
Get the service type instance associated with service_type_id.
afw_environment_foreach(int type_number, afw_environment_foreach_cb_t callback, void *data, const afw_pool_t *p, afw_xctx_t *xctx)
Call a callback function for each entry of a registry type.
afw_service_t * afw_environment_get_service(const afw_utf8_t *service_id, afw_xctx_t *xctx)
Get the service instance associated with service_id.
#define AFW_FINALLY
Always executed regardless of error.
Definition: afw_error.h:702
#define AFW_CATCH_UNHANDLED
Catch an unhandled error that occurs in a AFW_TRY block.
Definition: afw_error.h:684
afw_error_write_log(afw_log_priority_t priority, const afw_error_t *error, afw_xctx_t *xctx)
Write error to environment log.
Definition: afw_error.c:639
#define AFW_THROW_ERROR_RV_Z(code, rv_source_id, rv, message_z, xctx)
Macro used to set error and rv in xctx and throw it.
Definition: afw_error.h:301
#define AFW_ENDTRY
Ends an AFW try block.
Definition: afw_error.h:727
#define AFW_TRY
Begin an AFW TRY block.
Definition: afw_error.h:634
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:319
afw_error_to_utf8(const afw_error_t *error, const afw_pool_t *p, afw_xctx_t *xctx)
Convert error to utf8.
Definition: afw_error.c:547
#define AFW_MARK_UNHANDLED
Use in an AFW_CATCH or AFW_CATCH_UNHANDLED block to mark error as unhandled and break.
Definition: afw_error.h:750
#define AFW_ERROR_THROWN
Access the thrown error. See AFW_TRY.
Definition: afw_error.h:554
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
#define AFW_CATCH(__CODE_)
Catch a particular error that occurs in a AFW_TRY block.
Definition: afw_error.h:668
#define AFW_LOG_FZ(priority, xctx, format_z,...)
Log an message to environment's log using a printf style format and parameters.
Definition: afw_log.h:192
#define AFW_LOG_Z(priority, message_z, xctx)
Log an afw_utf8_z_t message to environment's log.
Definition: afw_log.h:168
#define afw_memory_clear(to)
Clear preallocated memory for sizeof(*(to)).
Definition: afw_memory.h:47
void * afw_memory_dup(const void *from, apr_size_t size, const afw_pool_t *p, afw_xctx_t *xctx)
Duplicate a block of memory into specified pool.
Definition: afw_memory.h:88
#define afw_object_get_property(instance, property_name, xctx)
Call method get_property of interface afw_object.
afw_object_meta_get_path(const afw_object_t *instance, afw_xctx_t *xctx)
Get an object's path.
afw_object_meta_set_object_type_id(const afw_object_t *instance, const afw_utf8_t *object_type_id, afw_xctx_t *xctx)
Set object's object type id.
afw_object_meta_set_ids(const afw_object_t *instance, const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, afw_xctx_t *xctx)
Set object's ids.
afw_object_meta_get_object_id(const afw_object_t *instance, afw_xctx_t *xctx)
Get entity object's object id.
afw_object_create_clone(const afw_object_t *object, const afw_pool_t *p, afw_xctx_t *xctx)
Clone an object to a specified pool.
Definition: afw_memory.c:138
#define afw_object_create_managed(p, xctx)
Create an empty entity object in its own pool.
Definition: afw_object.h:913
#define afw_object_create(p, xctx)
Create an empty unmanaged object in memory.
Definition: afw_object.h:948
afw_object_set_property(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_value_t *value, afw_xctx_t *xctx)
Set the value of an object's property.
Definition: afw_object.c:46
#define afw_pool_get_apr_pool(instance)
Call method get_apr_pool of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
const afw_pool_t * afw_pool_create_multithreaded(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new multithreaded pool.
afw_query_criteria_test_object(const afw_object_t *obj, const afw_query_criteria_t *criteria, const afw_pool_t *p, afw_xctx_t *xctx)
Test object against query criteria.
#define afw_service_type_start_cede_p(instance, properties, p, xctx)
Call method start_cede_p of interface afw_service_type.
#define afw_service_type_restart_cede_p(instance, properties, p, xctx)
Call method restart_cede_p of interface afw_service_type.
#define afw_service_type_related_instance_count(instance, id, xctx)
Call method related_instance_count of interface afw_service_type.
#define afw_service_type_stop(instance, id, xctx)
Call method stop of interface afw_service_type.
afw_service_startup_description(afw_service_startup_t startup)
Get description for a afw_service_startup_t enum.
Definition: afw_service.c:165
afw_service_restart(const afw_utf8_t *service_id, afw_xctx_t *xctx)
Restart a service.
Definition: afw_service.c:1465
afw_service_startup_as_value(afw_service_startup_t startup)
Convert afw_service_startup_t enum to corresponding adaptive value.
Definition: afw_service.c:150
afw_service_start_using_AdaptiveConf_cede_p(const afw_object_t *conf, const afw_utf8_t *source_location, const afw_pool_t *p, afw_xctx_t *xctx)
Start a service using AdaptiveConf object and cede p.
Definition: afw_service.c:1147
afw_service_stop(const afw_utf8_t *service_id, afw_xctx_t *xctx)
Stop a service.
Definition: afw_service.c:1266
const afw_object_t * afw_service_get_object(const afw_utf8_t *service_id, const afw_pool_t *p, afw_xctx_t *xctx)
Get a service object by service id.
Definition: afw_service.c:1058
const afw_utf8_t * afw_service_status_description(afw_service_status_t status)
Get description for a afw_service_status_t enum.
Definition: afw_service.c:240
afw_service_status_as_enum(const afw_utf8_t *s)
Convert utf8 to corresponding afw_service_status_t enum.
Definition: afw_service.c:270
afw_service_status_as_utf8(afw_service_status_t status)
Convert afw_service_status_t enum to corresponding utf8.
Definition: afw_service.c:210
const afw_value_t * afw_service_status_description_as_value(afw_service_status_t status)
Get description as value for a afw_service_status_t enum.
Definition: afw_service.c:255
afw_service_startup_description_as_value(afw_service_startup_t startup)
Get description as value for a afw_service_startup_t enum.
Definition: afw_service.c:180
afw_service_status_as_value(afw_service_status_t status)
Convert afw_service_status_t enum to corresponding adaptive value.
Definition: afw_service.c:225
afw_service_startup_as_utf8(afw_service_startup_t startup)
Convert afw_service_startup_t enum to corresponding utf8.
Definition: afw_service.c:135
afw_service_start(const afw_utf8_t *service_id, afw_boolean_t manual_start, afw_xctx_t *xctx)
Start a service.
Definition: afw_service.c:1201
afw_service_startup_t afw_service_startup_as_enum(const afw_utf8_t *s)
Convert utf8 to corresponding afw_service_startup_t enum.
Definition: afw_service.c:195
#define AFW_THREAD_MUTEX_UNLOCK()
Macro to end a mutex lock.
Definition: afw_thread.h:151
#define AFW_THREAD_MUTEX_LOCK(mutex, xctx)
Macro to begin a mutex lock section.
Definition: afw_thread.h:137
afw_dateTime_set_now(afw_dateTime_t *dateTime_local, afw_dateTime_t *dateTime_utc, afw_xctx_t *xctx)
Set local and/or utc dateTime to now.
Definition: afw_time.c:523
#define afw_utf8_create_copy(s, len, p, xctx)
Make a utf-8 sting from chars in pool specified.
Definition: afw_utf8.h:369
afw_boolean_t afw_utf8_equal(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string equals another string.
const afw_utf8_t * afw_utf8_clone(const afw_utf8_t *string, const afw_pool_t *p, afw_xctx_t *xctx)
Clone a utf-8 string into a specific pool.
Definition: afw_utf8.h:347
afw_utf8_printf(const afw_pool_t *p, afw_xctx_t *xctx, const afw_utf8_z_t *format,...)
Create a utf-8 string using a c format string in specified pool.
Definition: afw_utf8.c:459
Internal request info used by afw_adaptor_impl*() functions.
Interface afw_adaptor_session public struct.
const afw_utf8_t * subtype_property_name
Subtype property name for instances of this conf type.
const afw_utf8_t * id_property_name
Id property name for instances of this conf type.
const afw_utf8_t * id_runtime_object_type_id
Runtime object type for instances of this conf type.
const afw_pool_t * p
Pool used to hold environment.
Definition: afw_common.h:1386
const afw_adaptor_t * conf_adaptor
Adaptor for application.confAdaptorId or NULL.
Definition: afw_common.h:1401
Interface afw_object public struct.
Interface afw_pool public struct.
Parsed query criteria.
Runtime service struct.
Definition: afw_service.h:46
const afw_utf8_t * status_message
Optional status message.
Definition: afw_service.h:97
afw_utf8_t service_id
Service's name.
Definition: afw_service.h:59
const afw_utf8_t * conf_source_location
The source location associated with the conf for this service.
Definition: afw_service.h:84
afw_thread_mutex_t * mutex
Mutex used when changing status.
Definition: afw_service.h:107
afw_dateTime_t start_time
Start time.
Definition: afw_service.h:90
afw_boolean_t has_service_conf
Has a service conf object.
Definition: afw_service.h:113
const afw_pool_t * p
Pool that holds service's resources.
Definition: afw_service.h:49
const afw_utf8_t * source_location
The source location associated with this service.
Definition: afw_service.h:78
const afw_service_type_t * service_type
afw_service_type instance for this service_type_id.
Definition: afw_service.h:69
const afw_utf8_t * conf_subtype
This is the value of the subtype property from conf or NULL.
Definition: afw_service.h:75
const afw_utf8_t * status_debug
Optional status debug.
Definition: afw_service.h:104
const afw_utf8_t * type
The part before the dash ('-') in service_id.
Definition: afw_service.h:66
const afw_utf8_t * conf_id
The part after the dash ('-') in the service id.
Definition: afw_service.h:72
const afw_object_t * properties
The properties object containing runtime and conf properties.
Definition: afw_service.h:81
afw_service_status_t status
The status of the service.
Definition: afw_service.h:87
Interface afw_service_type public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Interface afw_value public struct.
struct for data type string values.
Interface afw_xctx public struct.