00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "service.h"
00036 #include "core_services.h"
00037 #include "mutex.h"
00038 #include "node.h"
00039 #include "settings.h"
00040 #include <copy.h>
00041 #include <list.h>
00042 #include <http_common.h>
00043 #include <io.h>
00044 #include <str.h>
00045 #include <type.h>
00046 #include <xml.h>
00047
00048 #include <assert.h>
00049 #include <apr_pools.h>
00050 #include <apr_file_io.h>
00051 #include <apr_strings.h>
00052 #include <stdio.h>
00053
00054 extern apr_pool_t *global_mp;
00055
00059 static bs_list *services_pool = NULL;
00060
00064 typedef struct service_info
00065 {
00066 bs_definition *def;
00067 service_request_handler handler;
00068 } service_info;
00069
00070
00071 bs_status init_service(apr_pool_t *mp)
00072 {
00073 bs_status rv;
00074 bs_uint64 len;
00075 bs_definition *def = NULL;
00076 char *buf, *fname;
00077 unsigned type;
00078
00079 services_pool = new_list(mp);
00080
00081
00082 fname = apr_pstrcat(mp, BIOSPHERED_PREFIX, "/bin/",
00083 CORE_SERVICES_DEFINITION_FILE, NULL);
00084 rv = read_file_into_buf(fname, &buf, &len, mp);
00085 if (rv != BS_OK) {
00086 fprintf(stderr, "%d Error while reading core services definition file: %s\n", rv, fname);
00087 return rv;
00088 }
00089
00090
00091 rv = xlate_from_xml(buf, len, (void **) &def, &type, mp);
00092 if (rv != BS_OK) {
00093 fprintf(stderr, "%d Error while parsing core services definition file: %s\n", rv, fname);
00094 return rv;
00095 }
00096 rv = add_service(def, &core_service_request_handler);
00097 if (rv != BS_OK) {
00098 fprintf(stderr, "%d Error while adding core services\n", rv);
00099 return rv;
00100 }
00101 return BS_OK;
00102 }
00103
00104
00105 bs_status add_service(bs_definition *def, service_request_handler handler)
00106 {
00107 service_info *info;
00108 unsigned i;
00109
00110
00111 lock_service_mux();
00112 for (i = 0; i < list_size(services_pool); i++) {
00113 bs_definition *tmp = ((service_info *) list_index(services_pool, i))->def;
00114 if (streq(def->name, tmp->name)) {
00115 fprintf(stderr, "Service with the same name already exists: %s\n", def->name);
00116 unlock_service_mux();
00117 return BS_SERVICE_DOUBLE;
00118 }
00119 }
00120 unlock_service_mux();
00121
00122
00123 lock_pool_mux();
00124 info = (service_info *) apr_pcalloc(global_mp, sizeof(service_info));
00125 unlock_pool_mux();
00126 info->def = def;
00127 info->handler = handler;
00128 lock_service_mux();
00129 list_append(services_pool, info);
00130 unlock_service_mux();
00131
00132 return BS_OK;
00133 }
00134
00135
00136 bs_status remove_service(const char *name)
00137 {
00138 unsigned i;
00139
00140 lock_service_mux();
00141 for (i = 0; i < list_size(services_pool); i++) {
00142 bs_definition *def = ((service_info *) list_index(services_pool, i))->def;
00143 if (streq(name, def->name)) {
00144 list_remove(services_pool, i);
00145 unlock_service_mux();
00146 return BS_OK;
00147 }
00148 }
00149 unlock_service_mux();
00150 return BS_OK;
00151 }
00152
00153
00154 bs_status get_services(bs_definition **def, apr_pool_t *mp)
00155 {
00156 bs_definition *result = NULL;
00157 unsigned i;
00158
00159 lock_service_mux();
00160 result = new_bs_definition(mp, "service_definitions", 0, 0, 0, 0);
00161 for (i = 0; i < list_size(services_pool); i++) {
00162 bs_status rv;
00163 service_info *info = list_index(services_pool, i);
00164 rv = merge_def_with_def(mp, result, info->def);
00165 if (rv != BS_OK) {
00166 unlock_service_mux();
00167 return BS_ERROR;
00168 }
00169 }
00170
00171 unlock_service_mux();
00172 *def = result;
00173 return BS_OK;
00174 }
00175
00176
00184 static bs_status handle_service_request_remotely(
00185 const bs_service_request *request,
00186 bs_service_response **response, apr_pool_t *mp)
00187 {
00188 bs_service_response *resp;
00189 node_info *ni;
00190 bs_status rv;
00191
00192
00193 ni = get_servicing_node(request);
00194 if (!ni) return BS_NO_SERVICE;
00195
00196
00197 rv = connect_and_post(request, &resp, ni->address->address,
00198 ni->address->port, mp);
00199 if (rv != BS_OK) return rv;
00200 *response = resp;
00201 return BS_OK;
00202 }
00203
00204
00205 bs_status handle_service_request(const bs_service_request *request,
00206 bs_service_response **response, void *mp)
00207 {
00208 bs_status rv;
00209 bs_service_response *resp;
00210 apr_pool_t *pool;
00211 unsigned i;
00212 assert(request != NULL);
00213
00214
00215
00216
00217
00218 if (mp == NULL) {
00219 apr_status_t rv2;
00220 lock_pool_mux();
00221 rv2 = apr_pool_create(&pool, global_mp);
00222 unlock_pool_mux();
00223 if (rv2 != APR_SUCCESS) {
00224 fprintf(stderr, "could not create memory pool");
00225 return BS_ERROR;
00226 }
00227 }
00228 else pool = mp;
00229
00230
00231
00232
00233 lock_service_mux();
00234 for (i = 0; i < list_size(services_pool); i++) {
00235 service_info *si = list_index(services_pool, i);
00236 if (request_corresponds_with_definition(request, si->def)) {
00237 unlock_service_mux();
00238 rv = si->handler(request, &resp, pool);
00239 if (rv == BS_OK) {
00240 if (mp == NULL) {
00241
00242
00243
00244 *response = copy_response(resp);
00245 apr_pool_destroy(pool);
00246 }
00247 else {
00248
00249
00250
00251
00252 *response = resp;
00253 }
00254 }
00255 return rv;
00256 }
00257 }
00258 unlock_service_mux();
00259
00260
00261
00262 rv = handle_service_request_remotely(request, &resp, pool);
00263 if (rv == BS_OK) {
00264 if (mp == NULL) {
00265 *response = copy_response(resp);
00266 apr_pool_destroy(pool);
00267 }
00268 else {
00269 *response = resp;
00270 }
00271 }
00272
00273 return rv;
00274 }