Line |
Branch |
Exec |
Source |
1 |
|
|
/* GATE PROJECT LICENSE: |
2 |
|
|
+----------------------------------------------------------------------------+ |
3 |
|
|
| Copyright(c) 2018-2025, Stefan Meislinger | |
4 |
|
|
| All rights reserved. | |
5 |
|
|
| | |
6 |
|
|
| Redistribution and use in source and binary forms, with or without | |
7 |
|
|
| modification, are permitted provided that the following conditions are met:| |
8 |
|
|
| | |
9 |
|
|
| 1. Redistributions of source code must retain the above copyright notice, | |
10 |
|
|
| this list of conditions and the following disclaimer. | |
11 |
|
|
| 2. Redistributions in binary form must reproduce the above copyright | |
12 |
|
|
| notice, this list of conditions and the following disclaimer in the | |
13 |
|
|
| documentation and/or other materials provided with the distribution. | |
14 |
|
|
| | |
15 |
|
|
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| |
16 |
|
|
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
17 |
|
|
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
18 |
|
|
| ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
19 |
|
|
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
20 |
|
|
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
21 |
|
|
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
22 |
|
|
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
23 |
|
|
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
24 |
|
|
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
25 |
|
|
| THE POSSIBILITY OF SUCH DAMAGE. | |
26 |
|
|
+----------------------------------------------------------------------------+ |
27 |
|
|
*/ |
28 |
|
|
|
29 |
|
|
#include "gate/tech/gateservices.h" |
30 |
|
|
#include "gate/results.h" |
31 |
|
|
#include "gate/utilities.h" |
32 |
|
|
#include "gate/synchronization.h" |
33 |
|
|
#include "gate/structs.h" |
34 |
|
|
#include "gate/tech/microservices/webserver_service.h" |
35 |
|
|
#include "gate/tech/microservices/timer_service.h" |
36 |
|
|
#include "gate/tech/microservices/procrunner_service.h" |
37 |
|
|
#include "gate/io/logging.h" |
38 |
|
|
#include "gate/encode/yaml.h" |
39 |
|
|
#include "gate/encode/json.h" |
40 |
|
|
|
41 |
|
|
|
42 |
|
|
|
43 |
|
|
#define GATE_STRUCT_SERVICEHOST_ROOT_NAME "servicehost" |
44 |
|
|
|
45 |
|
|
#define GATE_SERVICEHOST_CONFIG_SERVICE_NAME GATE_STRUCT_ROOT_NAME GATE_STRUCT_SEPARATOR GATE_STRUCT_SERVICEHOST_ROOT_NAME GATE_STRUCT_SEPARATOR "config_service" |
46 |
|
|
|
47 |
|
|
static gate_struct_item_t const config_service_members[] = |
48 |
|
|
{ |
49 |
|
|
GATE_STRUCT_ITEM_EX(gate_servicehost_config_service_t, GATE_TYPE_STRING, name, "Service class name", GATE_STRUCT_FLAG_DEFAULT), |
50 |
|
|
GATE_STRUCT_ITEM_EX(gate_servicehost_config_service_t, GATE_TYPE_STRING, instance, "Service instance identifier", GATE_STRUCT_FLAG_DEFAULT), |
51 |
|
|
GATE_STRUCT_ITEM_EX(gate_servicehost_config_service_t, GATE_TYPE_ARRAYLIST_STRING, msg_subscriptions, "Message subscriptions", GATE_STRUCT_FLAG_DEFAULT), |
52 |
|
|
GATE_STRUCT_ITEM_EX(gate_servicehost_config_service_t, GATE_TYPE_ARRAYLIST_STRING, obj_subscriptions, "Object subscriptions", GATE_STRUCT_FLAG_DEFAULT), |
53 |
|
|
GATE_STRUCT_ITEM_EX(gate_servicehost_config_service_t, GATE_TYPE_STRING, service_group, "Service execution group name", GATE_STRUCT_FLAG_DEFAULT), |
54 |
|
|
GATE_STRUCT_ITEM_EX(gate_servicehost_config_service_t, GATE_TYPE_BOOL, autostart, "Automatic start of service", GATE_STRUCT_FLAG_DEFAULT), |
55 |
|
|
GATE_STRUCT_ITEM_EX(gate_servicehost_config_service_t, GATE_TYPE_UI32, startorder, "Start order of service", GATE_STRUCT_FLAG_DEFAULT), |
56 |
|
|
GATE_STRUCT_ITEM_EX(gate_servicehost_config_service_t, GATE_TYPE_PROPERTY, parameters, "Service internal parameters", GATE_STRUCT_FLAG_DEFAULT) |
57 |
|
|
}; |
58 |
|
|
|
59 |
|
|
static gate_struct_descriptor_t const config_service_descriptor = |
60 |
|
|
{ |
61 |
|
|
GATE_SERVICEHOST_CONFIG_SERVICE_NAME, |
62 |
|
|
config_service_members, |
63 |
|
|
sizeof(config_service_members) / sizeof(config_service_members[0]), |
64 |
|
|
sizeof(gate_servicehost_config_service_t) |
65 |
|
|
}; |
66 |
|
|
|
67 |
|
✗ |
gate_result_t gate_servicehost_config_service_copy_constructor(void* dest, void const* src) |
68 |
|
|
{ |
69 |
|
|
gate_result_t result; |
70 |
|
✗ |
gate_servicehost_config_service_t* ptr = (gate_servicehost_config_service_t*)dest; |
71 |
|
✗ |
gate_struct_t const* ptr_src = (gate_struct_t const*)src; |
72 |
|
|
|
73 |
|
✗ |
gate_mem_clear(&ptr->struct_base, sizeof(gate_servicehost_config_service_t)); |
74 |
|
✗ |
if (ptr_src) |
75 |
|
|
{ |
76 |
|
✗ |
result = gate_struct_copy(&ptr->struct_base, ptr_src); |
77 |
|
|
} |
78 |
|
|
else |
79 |
|
|
{ |
80 |
|
✗ |
result = gate_struct_init(&ptr->struct_base, &config_service_descriptor); |
81 |
|
|
} |
82 |
|
✗ |
return result; |
83 |
|
|
} |
84 |
|
|
|
85 |
|
✗ |
gate_result_t gate_servicehost_config_service_init(gate_struct_t* ptr) |
86 |
|
|
{ |
87 |
|
✗ |
gate_result_t result = gate_servicehost_config_service_copy_constructor(ptr, NULL); |
88 |
|
✗ |
return result; |
89 |
|
|
} |
90 |
|
|
|
91 |
|
|
|
92 |
|
|
|
93 |
|
|
#define GATE_STRUCT_GSVC_CONFIG_NAME GATE_STRUCT_ROOT_NAME GATE_STRUCT_SEPARATOR GATE_STRUCT_SERVICEHOST_ROOT_NAME GATE_STRUCT_SEPARATOR "config" |
94 |
|
|
|
95 |
|
|
static gate_struct_item_t const config_members[] = |
96 |
|
|
{ |
97 |
|
|
GATE_STRUCT_ITEM(gate_servicehost_config_t, GATE_TYPE_STRING, id), |
98 |
|
|
GATE_STRUCT_ITEM(gate_servicehost_config_t, GATE_TYPE_STRING, version), |
99 |
|
|
GATE_STRUCT_ITEM(gate_servicehost_config_t, GATE_TYPE_ARRAYLIST_STRUCT, services) |
100 |
|
|
}; |
101 |
|
|
|
102 |
|
|
static gate_struct_descriptor_t const config_descriptor = |
103 |
|
|
{ |
104 |
|
|
GATE_STRUCT_GSVC_CONFIG_NAME, |
105 |
|
|
config_members, |
106 |
|
|
sizeof(config_members) / sizeof(config_members[0]), |
107 |
|
|
sizeof(gate_servicehost_config_t) |
108 |
|
|
}; |
109 |
|
|
|
110 |
|
|
|
111 |
|
✗ |
void* gate_servicehost_config_copy_constructor(void* dest, void const* src) |
112 |
|
|
{ |
113 |
|
✗ |
void* ret = NULL; |
114 |
|
|
gate_result_t result; |
115 |
|
✗ |
gate_servicehost_config_t* ptr = (gate_servicehost_config_t*)dest; |
116 |
|
✗ |
gate_mem_clear(ptr, sizeof(gate_servicehost_config_t)); |
117 |
|
|
|
118 |
|
✗ |
if (src) |
119 |
|
|
{ |
120 |
|
✗ |
result = gate_struct_copy(&ptr->struct_base, (gate_struct_t const*)src); |
121 |
|
|
} |
122 |
|
|
else |
123 |
|
|
{ |
124 |
|
✗ |
result = gate_struct_init(&ptr->struct_base, &config_descriptor); |
125 |
|
✗ |
ptr->services = gate_arraylist_create(sizeof(gate_servicehost_config_service_t), NULL, 0, |
126 |
|
|
&gate_servicehost_config_service_copy_constructor, &gate_struct_destructor); |
127 |
|
|
} |
128 |
|
✗ |
if (GATE_SUCCEEDED(result)) |
129 |
|
|
{ |
130 |
|
✗ |
ret = dest; |
131 |
|
|
} |
132 |
|
✗ |
return ret; |
133 |
|
|
} |
134 |
|
|
|
135 |
|
✗ |
gate_result_t gate_servicehost_config_init(gate_struct_t* ptr) |
136 |
|
|
{ |
137 |
|
✗ |
if (NULL == gate_servicehost_config_copy_constructor(ptr, NULL)) |
138 |
|
|
{ |
139 |
|
✗ |
return GATE_RESULT_FAILED; |
140 |
|
|
} |
141 |
|
|
else |
142 |
|
|
{ |
143 |
|
✗ |
return GATE_RESULT_OK; |
144 |
|
|
} |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
|
148 |
|
|
|
149 |
|
|
|
150 |
|
|
typedef struct gate_essentials_impl_class |
151 |
|
|
{ |
152 |
|
|
GATE_INTERFACE_VTBL(gate_microfactory) const* vtbl; |
153 |
|
|
|
154 |
|
|
gate_atomic_int_t ref_counter; |
155 |
|
|
} gate_essentials_impl_t; |
156 |
|
|
|
157 |
|
|
|
158 |
|
✗ |
static void essentials_destroy(gate_essentials_impl_t* impl) |
159 |
|
|
{ |
160 |
|
|
(void)impl; |
161 |
|
|
/* no deallocation, static object */ |
162 |
|
✗ |
} |
163 |
|
|
|
164 |
|
✗ |
static char const* essentials_get_interface_name(void* thisptr) |
165 |
|
|
{ |
166 |
|
✗ |
gate_essentials_impl_t* self = (gate_essentials_impl_t*)thisptr; |
167 |
|
|
(void)self; |
168 |
|
✗ |
return GATE_INTERFACE_NAME_MICROFACTORY; |
169 |
|
|
} |
170 |
|
✗ |
static void essentials_release(void* thisptr) |
171 |
|
|
{ |
172 |
|
✗ |
gate_essentials_impl_t* self = (gate_essentials_impl_t*)thisptr; |
173 |
|
✗ |
if (0 == gate_atomic_int_dec(&self->ref_counter)) |
174 |
|
|
{ |
175 |
|
✗ |
essentials_destroy(self); |
176 |
|
|
} |
177 |
|
✗ |
} |
178 |
|
✗ |
static int essentials_retain(void* thisptr) |
179 |
|
|
{ |
180 |
|
✗ |
gate_essentials_impl_t* self = (gate_essentials_impl_t*)thisptr; |
181 |
|
✗ |
return gate_atomic_int_inc(&self->ref_counter); |
182 |
|
|
} |
183 |
|
|
|
184 |
|
|
static gate_string_t name_webserver = GATE_STRING_INIT_STATIC(GATE_MICROSERVICE_NAME_WEBSERVER); |
185 |
|
|
static gate_string_t name_timer = GATE_STRING_INIT_STATIC(GATE_MICROSERVICE_NAME_TIMER); |
186 |
|
|
static gate_string_t name_procrunner = GATE_STRING_INIT_STATIC(GATE_MICROSERVICE_NAME_PROCRUNNER); |
187 |
|
|
|
188 |
|
|
typedef struct factory_mapping_class |
189 |
|
|
{ |
190 |
|
|
gate_string_t const* name; |
191 |
|
|
gate_microservice_creator_t creator; |
192 |
|
|
} factory_mapping_t; |
193 |
|
|
|
194 |
|
|
static factory_mapping_t essential_mappings[] = |
195 |
|
|
{ |
196 |
|
|
{ &name_webserver, &gate_microservice_webserver_create }, |
197 |
|
|
{ &name_timer, &gate_microservice_timer_create }, |
198 |
|
|
{ &name_procrunner, &gate_microservice_procrunner_create } |
199 |
|
|
}; |
200 |
|
|
|
201 |
|
|
|
202 |
|
✗ |
static gate_result_t essentials_supported_service_names(void* thisptr, gate_array_t* ptr_output_names) |
203 |
|
|
{ |
204 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
205 |
|
✗ |
gate_essentials_impl_t* self = (gate_essentials_impl_t*)thisptr; |
206 |
|
|
gate_size_t index; |
207 |
|
|
gate_size_t count; |
208 |
|
✗ |
gate_arraylist_t names = NULL; |
209 |
|
|
|
210 |
|
|
(void)self; |
211 |
|
|
do |
212 |
|
|
{ |
213 |
|
✗ |
count = sizeof(essential_mappings) / sizeof(essential_mappings[0]); |
214 |
|
|
|
215 |
|
✗ |
names = gate_util_stringarray_create_duplicate(count); |
216 |
|
✗ |
if (names == NULL) |
217 |
|
|
{ |
218 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
219 |
|
✗ |
break; |
220 |
|
|
} |
221 |
|
|
|
222 |
|
✗ |
for (index = 0; index != count; ++index) |
223 |
|
|
{ |
224 |
|
✗ |
gate_arraylist_add(names, essential_mappings[index].name); |
225 |
|
|
} |
226 |
|
|
|
227 |
|
✗ |
if (NULL == gate_array_create(ptr_output_names, names)) |
228 |
|
|
{ |
229 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
230 |
|
|
} |
231 |
|
|
else |
232 |
|
|
{ |
233 |
|
✗ |
ret = GATE_RESULT_OK; |
234 |
|
|
} |
235 |
|
|
} while (0); |
236 |
|
|
|
237 |
|
✗ |
if (names) |
238 |
|
|
{ |
239 |
|
✗ |
gate_arraylist_release(names); |
240 |
|
|
} |
241 |
|
|
|
242 |
|
✗ |
return ret; |
243 |
|
|
} |
244 |
|
✗ |
static gate_result_t essentials_create_service(void* thisptr, gate_string_t const* service_name, gate_microservice_t** ptr_service) |
245 |
|
|
{ |
246 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOMATCH; |
247 |
|
|
gate_size_t index, count; |
248 |
|
✗ |
gate_essentials_impl_t* self = (gate_essentials_impl_t*)thisptr; |
249 |
|
|
(void)self; |
250 |
|
|
|
251 |
|
|
do |
252 |
|
|
{ |
253 |
|
✗ |
count = sizeof(essential_mappings) / sizeof(essential_mappings[0]); |
254 |
|
|
|
255 |
|
✗ |
for (index = 0; index != count; ++index) |
256 |
|
|
{ |
257 |
|
✗ |
if (gate_string_equals(service_name, essential_mappings[index].name)) |
258 |
|
|
{ |
259 |
|
✗ |
ret = GATE_RESULT_OK; |
260 |
|
✗ |
if (ptr_service != NULL) |
261 |
|
|
{ |
262 |
|
✗ |
*ptr_service = essential_mappings[index].creator(); |
263 |
|
✗ |
if (*ptr_service == NULL) |
264 |
|
|
{ |
265 |
|
✗ |
ret = GATE_RESULT_FAILED; |
266 |
|
|
} |
267 |
|
|
} |
268 |
|
✗ |
break; |
269 |
|
|
} |
270 |
|
|
} |
271 |
|
|
} while (0); |
272 |
|
|
|
273 |
|
✗ |
return ret; |
274 |
|
|
} |
275 |
|
|
|
276 |
|
|
|
277 |
|
|
static GATE_INTERFACE_VTBL(gate_microfactory) gate_essentials_microfactory_vtbl; |
278 |
|
✗ |
static void gate_init_essentials_microfactory_vtbl() |
279 |
|
|
{ |
280 |
|
✗ |
if (!gate_essentials_microfactory_vtbl.get_interface_name) |
281 |
|
|
{ |
282 |
|
|
GATE_INTERFACE_VTBL(gate_microfactory) const local_vtbl = |
283 |
|
|
{ |
284 |
|
|
&essentials_get_interface_name, |
285 |
|
|
&essentials_release, |
286 |
|
|
&essentials_retain, |
287 |
|
|
|
288 |
|
|
&essentials_supported_service_names, |
289 |
|
|
&essentials_create_service |
290 |
|
|
}; |
291 |
|
✗ |
gate_essentials_microfactory_vtbl = local_vtbl; |
292 |
|
|
} |
293 |
|
✗ |
} |
294 |
|
|
|
295 |
|
|
static gate_essentials_impl_t global_essentials_factory = |
296 |
|
|
{ |
297 |
|
|
&gate_essentials_microfactory_vtbl, |
298 |
|
|
0 |
299 |
|
|
}; |
300 |
|
|
|
301 |
|
|
|
302 |
|
|
|
303 |
|
✗ |
GATE_TECH_API gate_microfactory_t* gate_servicehost_essentials_factory() |
304 |
|
|
{ |
305 |
|
✗ |
gate_microfactory_t* factory = (gate_microfactory_t*)&global_essentials_factory; |
306 |
|
|
|
307 |
|
✗ |
gate_init_essentials_microfactory_vtbl(); |
308 |
|
|
|
309 |
|
✗ |
gate_atomic_int_inc(&global_essentials_factory.ref_counter); |
310 |
|
✗ |
return factory; |
311 |
|
|
} |
312 |
|
|
|
313 |
|
|
|
314 |
|
|
|
315 |
|
|
|
316 |
|
|
|
317 |
|
|
|
318 |
|
|
|
319 |
|
|
|
320 |
|
|
typedef struct subscription_class |
321 |
|
|
{ |
322 |
|
|
gate_string_t source_address; |
323 |
|
|
gate_string_t destination_address; |
324 |
|
|
gate_string_t msg_id; |
325 |
|
|
void* user_param; |
326 |
|
|
gate_microservice_t* service; |
327 |
|
|
} subscription_t; |
328 |
|
|
|
329 |
|
✗ |
static void subscription_destroy(subscription_t* subscr) |
330 |
|
|
{ |
331 |
|
✗ |
gate_string_release(&subscr->source_address); |
332 |
|
✗ |
gate_string_release(&subscr->destination_address); |
333 |
|
✗ |
gate_string_release(&subscr->msg_id); |
334 |
|
✗ |
subscr->user_param = NULL; |
335 |
|
✗ |
if (subscr->service != NULL) |
336 |
|
|
{ |
337 |
|
✗ |
gate_object_release(subscr->service); |
338 |
|
|
} |
339 |
|
✗ |
} |
340 |
|
|
|
341 |
|
✗ |
static subscription_t* subscription_create( |
342 |
|
|
subscription_t* subscr, gate_string_t const* source, gate_string_t const* dest, gate_string_t const* msg_id, |
343 |
|
|
void* user_param, gate_microservice_t* service) |
344 |
|
|
{ |
345 |
|
✗ |
subscription_t* ret = NULL; |
346 |
|
|
|
347 |
|
|
do |
348 |
|
|
{ |
349 |
|
✗ |
gate_mem_clear(subscr, sizeof(subscription_t)); |
350 |
|
|
|
351 |
|
✗ |
if (NULL == gate_string_clone(&subscr->source_address, source)) |
352 |
|
|
{ |
353 |
|
✗ |
break; |
354 |
|
|
} |
355 |
|
✗ |
if (NULL == gate_string_clone(&subscr->destination_address, dest)) |
356 |
|
|
{ |
357 |
|
✗ |
break; |
358 |
|
|
} |
359 |
|
✗ |
if (NULL == gate_string_clone(&subscr->msg_id, msg_id)) |
360 |
|
|
{ |
361 |
|
✗ |
break; |
362 |
|
|
} |
363 |
|
✗ |
subscr->user_param = user_param; |
364 |
|
✗ |
subscr->service = service; |
365 |
|
✗ |
if (subscr->service != NULL) |
366 |
|
|
{ |
367 |
|
✗ |
gate_object_retain(subscr->service); |
368 |
|
|
} |
369 |
|
|
|
370 |
|
✗ |
ret = subscr; |
371 |
|
|
} while (0); |
372 |
|
|
|
373 |
|
✗ |
if (!ret) |
374 |
|
|
{ |
375 |
|
✗ |
subscription_destroy(subscr); |
376 |
|
|
} |
377 |
|
|
|
378 |
|
✗ |
return ret; |
379 |
|
|
} |
380 |
|
|
|
381 |
|
✗ |
static gate_result_t subscription_copy_ctor(void* dest, void const* source) |
382 |
|
|
{ |
383 |
|
✗ |
subscription_t const* src_ptr = (subscription_t const*)source; |
384 |
|
✗ |
subscription_t* dst_ptr = subscription_create((subscription_t*)dest, |
385 |
|
|
&src_ptr->source_address, &src_ptr->destination_address, |
386 |
|
|
&src_ptr->msg_id, src_ptr->user_param, src_ptr->service); |
387 |
|
✗ |
if (NULL == dst_ptr) |
388 |
|
|
{ |
389 |
|
✗ |
return GATE_RESULT_OUTOFMEMORY; |
390 |
|
|
} |
391 |
|
|
else |
392 |
|
|
{ |
393 |
|
✗ |
return GATE_RESULT_OK; |
394 |
|
|
} |
395 |
|
|
} |
396 |
|
|
|
397 |
|
✗ |
static void subscription_dtor(void* dest) |
398 |
|
|
{ |
399 |
|
✗ |
subscription_destroy((subscription_t*)dest); |
400 |
|
✗ |
} |
401 |
|
|
|
402 |
|
|
|
403 |
|
|
typedef struct gate_servicehost_impl_class |
404 |
|
|
{ |
405 |
|
|
GATE_INTERFACE_VTBL(gate_servicehost) const* vtbl; |
406 |
|
|
|
407 |
|
|
gate_atomic_int_t ref_counter; |
408 |
|
|
|
409 |
|
|
gate_mutex_t lock; |
410 |
|
|
gate_map_t factories; /* map: (string)name -> (object)gate_microfactory_t */ |
411 |
|
|
gate_map_t services; /* map: (string)name -> (object)gate_microservice_t */ |
412 |
|
|
gate_map_t services_configs; /* map: (string)name -> [map: (ui32)id -> (value)value] */ |
413 |
|
|
gate_arraylist_t msg_subscriptions; /* subscription_t[] */ |
414 |
|
|
gate_arraylist_t obj_subscriptions; /* subscription_t[] */ |
415 |
|
|
gate_logger_t const* logger; |
416 |
|
|
|
417 |
|
|
|
418 |
|
|
} gate_servicehost_impl_t; |
419 |
|
|
|
420 |
|
✗ |
static gate_result_t gsvchost_init_members(gate_servicehost_impl_t* impl) |
421 |
|
|
{ |
422 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
423 |
|
|
|
424 |
|
|
do |
425 |
|
|
{ |
426 |
|
✗ |
gate_atomic_int_init(&impl->ref_counter, 1); |
427 |
|
|
|
428 |
|
✗ |
ret = gate_mutex_create(&impl->lock); |
429 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
430 |
|
|
|
431 |
|
✗ |
if (NULL == gate_map_create(&impl->factories, &gate_compare_string, |
432 |
|
|
sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor, |
433 |
|
|
sizeof(gate_object_t*), &gate_object_ptr_copyctor, &gate_object_ptr_dtor)) |
434 |
|
|
{ |
435 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
436 |
|
✗ |
break; |
437 |
|
|
} |
438 |
|
|
|
439 |
|
✗ |
if (NULL == gate_map_create(&impl->services, &gate_compare_string, |
440 |
|
|
sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor, |
441 |
|
|
sizeof(gate_object_t*), &gate_object_ptr_copyctor, &gate_object_ptr_dtor)) |
442 |
|
|
{ |
443 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
444 |
|
✗ |
break; |
445 |
|
|
} |
446 |
|
|
|
447 |
|
✗ |
if (NULL == gate_map_create(&impl->services_configs, &gate_compare_string, |
448 |
|
|
sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor, |
449 |
|
|
sizeof(gate_map_t), &gate_map_copy_constructor, &gate_map_destructor)) |
450 |
|
|
{ |
451 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
452 |
|
✗ |
break; |
453 |
|
|
} |
454 |
|
|
|
455 |
|
✗ |
impl->msg_subscriptions = gate_arraylist_create(sizeof(subscription_t), NULL, 0, &subscription_copy_ctor, &subscription_dtor); |
456 |
|
✗ |
if (NULL == impl->msg_subscriptions) |
457 |
|
|
{ |
458 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
459 |
|
✗ |
break; |
460 |
|
|
} |
461 |
|
|
|
462 |
|
✗ |
impl->obj_subscriptions = gate_arraylist_create(sizeof(subscription_t), NULL, 0, &subscription_copy_ctor, &subscription_dtor); |
463 |
|
✗ |
if (NULL == impl->obj_subscriptions) |
464 |
|
|
{ |
465 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
466 |
|
✗ |
break; |
467 |
|
|
} |
468 |
|
|
|
469 |
|
✗ |
impl->logger = gate_logger_get(); |
470 |
|
|
|
471 |
|
|
} while (0); |
472 |
|
|
|
473 |
|
✗ |
return ret; |
474 |
|
|
} |
475 |
|
|
|
476 |
|
|
|
477 |
|
✗ |
static void gsvchost_destroy(gate_servicehost_impl_t* impl) |
478 |
|
|
{ |
479 |
|
✗ |
gate_arraylist_release(impl->obj_subscriptions); |
480 |
|
✗ |
gate_arraylist_release(impl->msg_subscriptions); |
481 |
|
✗ |
gate_map_destroy(&impl->services_configs); |
482 |
|
✗ |
gate_map_destroy(&impl->services); |
483 |
|
✗ |
gate_map_destroy(&impl->factories); |
484 |
|
✗ |
gate_mutex_destroy(&impl->lock); |
485 |
|
|
|
486 |
|
✗ |
gate_mem_dealloc(impl); |
487 |
|
✗ |
} |
488 |
|
|
|
489 |
|
✗ |
static char const* gsvchost_get_interface_name(void* this_ptr) |
490 |
|
|
{ |
491 |
|
|
(void)this_ptr; |
492 |
|
✗ |
return GATE_INTERFACE_NAME_GATESERVICEHOST; |
493 |
|
|
} |
494 |
|
✗ |
static void gsvchost_release(void* this_ptr) |
495 |
|
|
{ |
496 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
497 |
|
✗ |
if (0 == gate_atomic_int_dec(&impl->ref_counter)) |
498 |
|
|
{ |
499 |
|
✗ |
gsvchost_destroy(impl); |
500 |
|
|
} |
501 |
|
✗ |
} |
502 |
|
✗ |
static int gsvchost_retain(void* this_ptr) |
503 |
|
|
{ |
504 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
505 |
|
✗ |
return gate_atomic_int_inc(&impl->ref_counter); |
506 |
|
|
} |
507 |
|
|
|
508 |
|
✗ |
static gate_size_t extract_subscriptions(gate_arraylist_t source, subscription_t* subscrs, gate_size_t max_subscrs, |
509 |
|
|
gate_string_t const* source_address, gate_string_t const* destination_address, |
510 |
|
|
gate_string_t const* msg_id) |
511 |
|
|
{ |
512 |
|
✗ |
gate_size_t ret = 0; |
513 |
|
|
gate_size_t index; |
514 |
|
✗ |
gate_size_t count = gate_arraylist_length(source); |
515 |
|
|
subscription_t const* ptr; |
516 |
|
|
gate_result_t result; |
517 |
|
|
|
518 |
|
✗ |
for (index = 0; (max_subscrs != 0) && (index != count); ++index) |
519 |
|
|
{ |
520 |
|
✗ |
ptr = (subscription_t const*)gate_arraylist_get(source, index); |
521 |
|
✗ |
if (ptr != NULL) |
522 |
|
|
{ |
523 |
|
✗ |
if (!gate_string_is_empty(source_address) && !gate_string_is_empty(&ptr->source_address)) |
524 |
|
|
{ |
525 |
|
✗ |
if (!gate_string_like(source_address, &ptr->source_address)) |
526 |
|
|
{ |
527 |
|
✗ |
continue; |
528 |
|
|
} |
529 |
|
|
} |
530 |
|
|
|
531 |
|
✗ |
if (!gate_string_is_empty(destination_address) && !gate_string_is_empty(&ptr->destination_address)) |
532 |
|
|
{ |
533 |
|
✗ |
if (!gate_string_like(destination_address, &ptr->destination_address)) |
534 |
|
|
{ |
535 |
|
✗ |
continue; |
536 |
|
|
} |
537 |
|
|
} |
538 |
|
|
|
539 |
|
✗ |
if (!gate_string_is_empty(msg_id) && !gate_string_is_empty(&ptr->msg_id)) |
540 |
|
|
{ |
541 |
|
✗ |
if (!gate_string_equals(msg_id, &ptr->msg_id)) |
542 |
|
|
{ |
543 |
|
✗ |
continue; |
544 |
|
|
} |
545 |
|
|
} |
546 |
|
|
|
547 |
|
|
/* copy this subscription */ |
548 |
|
✗ |
result = subscription_copy_ctor(subscrs, ptr); |
549 |
|
✗ |
if (GATE_SUCCEEDED(result)) |
550 |
|
|
{ |
551 |
|
✗ |
++ret; |
552 |
|
✗ |
++subscrs; |
553 |
|
✗ |
--max_subscrs; |
554 |
|
|
} |
555 |
|
|
} |
556 |
|
|
} |
557 |
|
✗ |
return ret; |
558 |
|
|
} |
559 |
|
✗ |
static void release_subscriptions(subscription_t* subscrs, gate_size_t count) |
560 |
|
|
{ |
561 |
|
✗ |
while (count-- != 0) |
562 |
|
|
{ |
563 |
|
✗ |
subscription_destroy(subscrs); |
564 |
|
✗ |
++subscrs; |
565 |
|
|
} |
566 |
|
✗ |
} |
567 |
|
|
|
568 |
|
✗ |
static gate_result_t gsvchost_publish_message(void* this_ptr, |
569 |
|
|
gate_string_t const* source_address, gate_string_t const* destination_address, |
570 |
|
|
gate_string_t const* msg_id, gate_string_t const* ptr_message) |
571 |
|
|
{ |
572 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
573 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
574 |
|
|
subscription_t subscriptions[128]; |
575 |
|
✗ |
gate_size_t subscriptions_extracted = 0; |
576 |
|
✗ |
gate_size_t index = 0; |
577 |
|
|
gate_result_t msg_result; |
578 |
|
|
static gate_string_t log_msg_origin = GATE_STRING_INIT_STATIC("microservice::publish_message"); |
579 |
|
✗ |
gate_strbuilder_t log_builder = GATE_INIT_EMPTY; |
580 |
|
|
char log_buffer[4096]; |
581 |
|
✗ |
gate_string_t log_text = GATE_STRING_INIT_EMPTY; |
582 |
|
✗ |
gate_uint32_t svc_status = 0; |
583 |
|
|
|
584 |
|
|
do |
585 |
|
|
{ |
586 |
|
|
{ |
587 |
|
✗ |
gate_strbuilder_create_static(&log_builder, log_buffer, sizeof(log_buffer), 0); |
588 |
|
✗ |
gate_strbuilder_append(&log_builder, |
589 |
|
|
GATE_PRINT_CSTR, "Publish message ID '", |
590 |
|
|
GATE_PRINT_STRING, msg_id, |
591 |
|
|
GATE_PRINT_CSTR, "' from '", |
592 |
|
|
GATE_PRINT_STRING, source_address, |
593 |
|
|
GATE_PRINT_CSTR, "' to '", |
594 |
|
|
GATE_PRINT_STRING, destination_address, |
595 |
|
|
GATE_PRINT_CSTR, "'", |
596 |
|
|
GATE_PRINT_END); |
597 |
|
✗ |
gate_strbuilder_to_string(&log_builder, &log_text); |
598 |
|
✗ |
gate_microhost_log(impl, GATE_LOG_TYPE_INFO, 0, 0, &log_msg_origin, &log_text); |
599 |
|
✗ |
gate_string_release(&log_text); |
600 |
|
✗ |
gate_strbuilder_release(&log_builder); |
601 |
|
|
} |
602 |
|
|
|
603 |
|
✗ |
gate_mem_clear(subscriptions, sizeof(subscriptions)); |
604 |
|
|
|
605 |
|
✗ |
ret = gate_mutex_acquire(&impl->lock); |
606 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
607 |
|
|
do |
608 |
|
|
{ |
609 |
|
✗ |
subscriptions_extracted = extract_subscriptions(impl->msg_subscriptions, |
610 |
|
|
subscriptions, sizeof(subscriptions) / sizeof(subscriptions[0]), |
611 |
|
|
source_address, destination_address, msg_id); |
612 |
|
|
} while (0); |
613 |
|
✗ |
gate_mutex_release(&impl->lock); |
614 |
|
|
|
615 |
|
✗ |
ret = GATE_RESULT_OK; |
616 |
|
✗ |
for (index = 0; index != subscriptions_extracted; ++index) |
617 |
|
|
{ |
618 |
|
✗ |
if (subscriptions[index].service) |
619 |
|
|
{ |
620 |
|
✗ |
svc_status = gate_microservice_get_status(subscriptions[index].service); |
621 |
|
|
|
622 |
|
✗ |
if (svc_status == GATE_MICROSERVICE_STATUS_ONLINE) |
623 |
|
|
{ |
624 |
|
|
{ |
625 |
|
✗ |
gate_strbuilder_create_static(&log_builder, log_buffer, sizeof(log_buffer), 0); |
626 |
|
✗ |
gate_strbuilder_append(&log_builder, |
627 |
|
|
GATE_PRINT_CSTR, "Delivering published message ID '", |
628 |
|
|
GATE_PRINT_STRING, msg_id, |
629 |
|
|
GATE_PRINT_CSTR, "' from '", |
630 |
|
|
GATE_PRINT_STRING, source_address, |
631 |
|
|
GATE_PRINT_CSTR, "' to '", |
632 |
|
|
GATE_PRINT_STRING, &subscriptions[index].destination_address, |
633 |
|
|
GATE_PRINT_CSTR, "'", |
634 |
|
|
GATE_PRINT_END); |
635 |
|
✗ |
gate_strbuilder_to_string(&log_builder, &log_text); |
636 |
|
✗ |
gate_microhost_log(impl, GATE_LOG_TYPE_INFO, 0, 0, &log_msg_origin, &log_text); |
637 |
|
✗ |
gate_string_release(&log_text); |
638 |
|
✗ |
gate_strbuilder_release(&log_builder); |
639 |
|
|
} |
640 |
|
|
|
641 |
|
✗ |
msg_result = gate_microservice_process_message(subscriptions[index].service, source_address, destination_address, |
642 |
|
|
msg_id, ptr_message, subscriptions[index].user_param); |
643 |
|
✗ |
if (GATE_FAILED(msg_result)) |
644 |
|
|
{ |
645 |
|
✗ |
gate_strbuilder_create_static(&log_builder, log_buffer, sizeof(log_buffer), 0); |
646 |
|
✗ |
gate_strbuilder_append(&log_builder, |
647 |
|
|
GATE_PRINT_CSTR, "Delivery of published message ID '", |
648 |
|
|
GATE_PRINT_STRING, msg_id, |
649 |
|
|
GATE_PRINT_CSTR, "' from '", |
650 |
|
|
GATE_PRINT_STRING, source_address, |
651 |
|
|
GATE_PRINT_CSTR, "' to '", |
652 |
|
|
GATE_PRINT_STRING, &subscriptions[index].destination_address, |
653 |
|
|
GATE_PRINT_CSTR, "' has failed", |
654 |
|
|
GATE_PRINT_END); |
655 |
|
✗ |
gate_strbuilder_to_string(&log_builder, &log_text); |
656 |
|
✗ |
gate_microhost_log(impl, GATE_LOG_TYPE_WARN, msg_result, 0, &log_msg_origin, &log_text); |
657 |
|
✗ |
gate_string_release(&log_text); |
658 |
|
✗ |
gate_strbuilder_release(&log_builder); |
659 |
|
|
} |
660 |
|
|
else |
661 |
|
|
{ |
662 |
|
✗ |
gate_strbuilder_create_static(&log_builder, log_buffer, sizeof(log_buffer), 0); |
663 |
|
✗ |
gate_strbuilder_append(&log_builder, |
664 |
|
|
GATE_PRINT_CSTR, "Delivery of published message ID '", |
665 |
|
|
GATE_PRINT_STRING, msg_id, |
666 |
|
|
GATE_PRINT_CSTR, "' from '", |
667 |
|
|
GATE_PRINT_STRING, source_address, |
668 |
|
|
GATE_PRINT_CSTR, "' to '", |
669 |
|
|
GATE_PRINT_STRING, &subscriptions[index].destination_address, |
670 |
|
|
GATE_PRINT_CSTR, "' succeeded", |
671 |
|
|
GATE_PRINT_END); |
672 |
|
✗ |
gate_strbuilder_to_string(&log_builder, &log_text); |
673 |
|
✗ |
gate_microhost_log(impl, GATE_LOG_TYPE_INFO, 0, 0, &log_msg_origin, &log_text); |
674 |
|
✗ |
gate_string_release(&log_text); |
675 |
|
✗ |
gate_strbuilder_release(&log_builder); |
676 |
|
|
} |
677 |
|
|
} |
678 |
|
|
else |
679 |
|
|
{ |
680 |
|
|
{ |
681 |
|
✗ |
gate_strbuilder_create_static(&log_builder, log_buffer, sizeof(log_buffer), 0); |
682 |
|
✗ |
gate_strbuilder_append(&log_builder, |
683 |
|
|
GATE_PRINT_CSTR, "Subscription target service '", |
684 |
|
|
GATE_PRINT_STRING, &subscriptions[index].destination_address, |
685 |
|
|
GATE_PRINT_CSTR, "' has invalid state #", |
686 |
|
|
GATE_PRINT_UI32, svc_status, |
687 |
|
|
GATE_PRINT_END); |
688 |
|
✗ |
gate_strbuilder_to_string(&log_builder, &log_text); |
689 |
|
✗ |
gate_microhost_log(impl, GATE_LOG_TYPE_WARN, 0, 0, &log_msg_origin, &log_text); |
690 |
|
✗ |
gate_string_release(&log_text); |
691 |
|
✗ |
gate_strbuilder_release(&log_builder); |
692 |
|
|
} |
693 |
|
|
|
694 |
|
|
} |
695 |
|
|
|
696 |
|
|
|
697 |
|
|
} |
698 |
|
|
} |
699 |
|
|
} while (0); |
700 |
|
|
|
701 |
|
✗ |
release_subscriptions(subscriptions, subscriptions_extracted); |
702 |
|
|
|
703 |
|
✗ |
return ret; |
704 |
|
|
} |
705 |
|
|
|
706 |
|
✗ |
static gate_result_t gsvchost_publish_object(void* this_ptr, |
707 |
|
|
gate_string_t const* source_address, gate_string_t const* destination_address, |
708 |
|
|
gate_string_t const* obj_id, gate_object_t* ptr_object) |
709 |
|
|
{ |
710 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
711 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
712 |
|
|
subscription_t subscriptions[128]; |
713 |
|
✗ |
gate_size_t subscriptions_extracted = 0; |
714 |
|
✗ |
gate_size_t index = 0; |
715 |
|
|
gate_result_t msg_result; |
716 |
|
|
|
717 |
|
|
do |
718 |
|
|
{ |
719 |
|
✗ |
gate_mem_clear(subscriptions, sizeof(subscriptions)); |
720 |
|
|
|
721 |
|
✗ |
ret = gate_mutex_acquire(&impl->lock); |
722 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
723 |
|
|
do |
724 |
|
|
{ |
725 |
|
✗ |
subscriptions_extracted = extract_subscriptions(impl->obj_subscriptions, |
726 |
|
|
subscriptions, sizeof(subscriptions) / sizeof(subscriptions[0]), |
727 |
|
|
source_address, destination_address, NULL); |
728 |
|
|
} while (0); |
729 |
|
✗ |
gate_mutex_release(&impl->lock); |
730 |
|
|
|
731 |
|
✗ |
ret = GATE_RESULT_OK; |
732 |
|
✗ |
for (index = 0; index != subscriptions_extracted; ++index) |
733 |
|
|
{ |
734 |
|
✗ |
if (subscriptions[index].service) |
735 |
|
|
{ |
736 |
|
✗ |
msg_result = gate_microservice_process_object(subscriptions[index].service, source_address, destination_address, |
737 |
|
|
obj_id, ptr_object, subscriptions[index].user_param); |
738 |
|
|
if (GATE_FAILED(msg_result)) |
739 |
|
|
{ |
740 |
|
|
/* TODO error logging */ |
741 |
|
|
} |
742 |
|
|
} |
743 |
|
|
} |
744 |
|
|
} while (0); |
745 |
|
|
|
746 |
|
✗ |
release_subscriptions(subscriptions, subscriptions_extracted); |
747 |
|
|
|
748 |
|
✗ |
return ret; |
749 |
|
|
} |
750 |
|
|
|
751 |
|
✗ |
static gate_result_t gsvchost_add_subscription(gate_servicehost_impl_t* impl, gate_arraylist_t subscription_list, |
752 |
|
|
gate_string_t const* source_address, gate_string_t const* destination_address, |
753 |
|
|
gate_string_t const* msg_id, gate_object_t* subscriber, void* user_data) |
754 |
|
|
{ |
755 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
756 |
|
|
subscription_t subscr; |
757 |
|
✗ |
gate_microservice_t* microservice = NULL; |
758 |
|
|
|
759 |
|
|
do |
760 |
|
|
{ |
761 |
|
✗ |
gate_mem_clear(&subscr, sizeof(subscr)); |
762 |
|
|
|
763 |
|
✗ |
if (subscriber != NULL) |
764 |
|
|
{ |
765 |
|
✗ |
if (!gate_object_implements_interface(subscriber, GATE_INTERFACE_NAME_MICROSERVICE)) |
766 |
|
|
{ |
767 |
|
✗ |
ret = GATE_RESULT_INVALIDARG; |
768 |
|
✗ |
break; |
769 |
|
|
} |
770 |
|
✗ |
microservice = (gate_microservice_t*)subscriber; |
771 |
|
|
} |
772 |
|
|
|
773 |
|
✗ |
if (NULL == subscription_create(&subscr, source_address, destination_address, msg_id, user_data, microservice)) |
774 |
|
|
{ |
775 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
776 |
|
✗ |
break; |
777 |
|
|
} |
778 |
|
|
|
779 |
|
✗ |
ret = gate_mutex_acquire(&impl->lock); |
780 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
781 |
|
|
do |
782 |
|
|
{ |
783 |
|
✗ |
if (NULL == gate_arraylist_add(subscription_list, &subscr)) |
784 |
|
|
{ |
785 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
786 |
|
|
} |
787 |
|
|
else |
788 |
|
|
{ |
789 |
|
✗ |
ret = GATE_RESULT_OK; |
790 |
|
|
} |
791 |
|
|
} while (0); |
792 |
|
✗ |
gate_mutex_release(&impl->lock); |
793 |
|
|
|
794 |
|
|
} while (0); |
795 |
|
|
|
796 |
|
✗ |
subscription_destroy(&subscr); |
797 |
|
✗ |
return ret; |
798 |
|
|
} |
799 |
|
|
|
800 |
|
✗ |
static gate_bool_t gsvchost_remove_subscription_filter(void const* item, void* param) |
801 |
|
|
{ |
802 |
|
✗ |
subscription_t const* ptr = (subscription_t const*)item; |
803 |
|
✗ |
subscription_t const* pattern = (subscription_t const*)param; |
804 |
|
✗ |
return (ptr->service == pattern->service) |
805 |
|
✗ |
|| (((pattern->service == NULL) || (ptr->service == NULL)) |
806 |
|
✗ |
&& gate_string_equals(&ptr->source_address, &pattern->source_address) |
807 |
|
✗ |
&& gate_string_equals(&ptr->destination_address, &pattern->destination_address) |
808 |
|
✗ |
&& gate_string_equals(&ptr->msg_id, &pattern->msg_id) |
809 |
|
|
); |
810 |
|
|
} |
811 |
|
|
|
812 |
|
✗ |
static gate_result_t gsvchost_remove_subscription(gate_servicehost_impl_t* impl, gate_arraylist_t subscription_list, |
813 |
|
|
gate_string_t const* source_address, gate_string_t const* destination_address, |
814 |
|
|
gate_string_t const* msg_id, gate_object_t* subscriber, void* user_data) |
815 |
|
|
{ |
816 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
817 |
|
|
subscription_t subscr; |
818 |
|
✗ |
gate_microservice_t* microservice = NULL; |
819 |
|
|
|
820 |
|
|
do |
821 |
|
|
{ |
822 |
|
✗ |
gate_mem_clear(&subscr, sizeof(subscr)); |
823 |
|
|
|
824 |
|
✗ |
if (subscriber != NULL) |
825 |
|
|
{ |
826 |
|
✗ |
if (!gate_object_implements_interface(subscriber, GATE_INTERFACE_NAME_MICROSERVICE)) |
827 |
|
|
{ |
828 |
|
✗ |
ret = GATE_RESULT_INVALIDARG; |
829 |
|
✗ |
break; |
830 |
|
|
} |
831 |
|
✗ |
microservice = (gate_microservice_t*)subscriber; |
832 |
|
|
} |
833 |
|
|
|
834 |
|
✗ |
if (NULL == subscription_create(&subscr, source_address, destination_address, msg_id, user_data, microservice)) |
835 |
|
|
{ |
836 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
837 |
|
✗ |
break; |
838 |
|
|
} |
839 |
|
|
|
840 |
|
✗ |
ret = gate_mutex_acquire(&impl->lock); |
841 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
842 |
|
|
do |
843 |
|
|
{ |
844 |
|
✗ |
ret = gate_arraylist_remove_if(subscription_list, &gsvchost_remove_subscription_filter, &subscr); |
845 |
|
|
} while (0); |
846 |
|
✗ |
gate_mutex_release(&impl->lock); |
847 |
|
|
|
848 |
|
|
} while (0); |
849 |
|
|
|
850 |
|
✗ |
subscription_destroy(&subscr); |
851 |
|
✗ |
return ret; |
852 |
|
|
} |
853 |
|
|
|
854 |
|
|
|
855 |
|
✗ |
static gate_result_t gsvchost_subscribe_messages( |
856 |
|
|
void* this_ptr, gate_string_t const* source_address, gate_string_t const* destination_address, |
857 |
|
|
gate_string_t const* msg_id, gate_object_t* subscriber, void* user_data) |
858 |
|
|
{ |
859 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
860 |
|
✗ |
return gsvchost_add_subscription(impl, impl->msg_subscriptions, source_address, destination_address, msg_id, subscriber, user_data); |
861 |
|
|
} |
862 |
|
✗ |
static gate_result_t gsvchost_unsubscribe_messages( |
863 |
|
|
void* this_ptr, gate_string_t const* source_address, gate_string_t const* destination_address, |
864 |
|
|
gate_string_t const* msg_id, gate_object_t* subscriber, void* user_data) |
865 |
|
|
{ |
866 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
867 |
|
✗ |
return gsvchost_remove_subscription(impl, impl->msg_subscriptions, source_address, destination_address, msg_id, subscriber, user_data); |
868 |
|
|
} |
869 |
|
|
|
870 |
|
✗ |
static gate_result_t gsvchost_subscribe_objects( |
871 |
|
|
void* this_ptr, gate_string_t const* source_address, gate_string_t const* destination_address, |
872 |
|
|
gate_string_t const* obj_id, gate_object_t* subscriber, void* user_data) |
873 |
|
|
{ |
874 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
875 |
|
✗ |
return gsvchost_add_subscription(impl, impl->obj_subscriptions, source_address, destination_address, obj_id, subscriber, user_data); |
876 |
|
|
} |
877 |
|
✗ |
static gate_result_t gsvchost_unsubscribe_objects( |
878 |
|
|
void* this_ptr, gate_string_t const* source_address, gate_string_t const* destination_address, |
879 |
|
|
gate_string_t const* obj_id, gate_object_t* subscriber, void* user_data) |
880 |
|
|
{ |
881 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
882 |
|
✗ |
return gsvchost_remove_subscription(impl, impl->obj_subscriptions, source_address, destination_address, obj_id, subscriber, user_data); |
883 |
|
|
} |
884 |
|
|
|
885 |
|
✗ |
static gate_result_t gsvchost_remote_invoke(void* this_ptr, gate_string_t const* destination_address, gate_string_t const* method, |
886 |
|
|
gate_struct_t const* input_data, gate_struct_t* output_data) |
887 |
|
|
{ |
888 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
889 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
890 |
|
✗ |
gate_microservice_t* service = NULL; |
891 |
|
|
|
892 |
|
|
do |
893 |
|
|
{ |
894 |
|
✗ |
ret = gate_servicehost_get_service(impl, destination_address, &service); |
895 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
896 |
|
|
|
897 |
|
✗ |
ret = gate_microservice_invoke(service, method, input_data, output_data); |
898 |
|
|
} while (0); |
899 |
|
|
|
900 |
|
✗ |
if (service != NULL) |
901 |
|
|
{ |
902 |
|
✗ |
gate_object_release(service); |
903 |
|
|
} |
904 |
|
✗ |
return ret; |
905 |
|
|
} |
906 |
|
|
|
907 |
|
✗ |
static gate_result_t gsvchost_log(void* this_ptr, gate_uint32_t svc_log_type, gate_result_t result_code, gate_int32_t native_code, |
908 |
|
|
gate_string_t const* origin, gate_string_t const* message) |
909 |
|
|
{ |
910 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
911 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
912 |
|
✗ |
gate_uint32_t logger_log_type = GATE_LOG_TYPE_INFO; |
913 |
|
|
do |
914 |
|
|
{ |
915 |
|
✗ |
if (impl->logger != NULL) |
916 |
|
|
{ |
917 |
|
✗ |
switch (svc_log_type) |
918 |
|
|
{ |
919 |
|
|
|
920 |
|
✗ |
case GATE_MICROSERVICE_LOGTYPE_DEBUG: logger_log_type = GATE_LOG_TYPE_DEBUG; break; |
921 |
|
✗ |
case GATE_MICROSERVICE_LOGTYPE_INFO: logger_log_type = GATE_LOG_TYPE_INFO; break; |
922 |
|
✗ |
case GATE_MICROSERVICE_LOGTYPE_STATUS: logger_log_type = GATE_LOG_TYPE_STATUS; break; |
923 |
|
✗ |
case GATE_MICROSERVICE_LOGTYPE_WARNING: logger_log_type = GATE_LOG_TYPE_WARN; break; |
924 |
|
✗ |
case GATE_MICROSERVICE_LOGTYPE_ERROR: logger_log_type = GATE_LOG_TYPE_ERROR; break; |
925 |
|
✗ |
case GATE_MICROSERVICE_LOGTYPE_ALERT: logger_log_type = GATE_LOG_TYPE_FATAL; break; |
926 |
|
|
} |
927 |
|
|
|
928 |
|
✗ |
ret = gate_log(impl->logger, logger_log_type, result_code, native_code, origin, message); |
929 |
|
|
} |
930 |
|
|
else |
931 |
|
|
{ |
932 |
|
✗ |
ret = GATE_RESULT_NOTREADY; |
933 |
|
|
} |
934 |
|
|
|
935 |
|
|
} while (0); |
936 |
|
|
|
937 |
|
✗ |
return ret; |
938 |
|
|
} |
939 |
|
|
|
940 |
|
✗ |
static gate_result_t gsvchost_add_factory(void* this_ptr, gate_microfactory_t* factory, gate_string_t const* factory_name) |
941 |
|
|
{ |
942 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
943 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
944 |
|
|
do |
945 |
|
|
{ |
946 |
|
✗ |
ret = gate_mutex_acquire(&impl->lock); |
947 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
948 |
|
|
|
949 |
|
✗ |
if (NULL == gate_map_add(&impl->factories, factory_name, &factory)) |
950 |
|
|
{ |
951 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
952 |
|
|
} |
953 |
|
✗ |
gate_mutex_release(&impl->lock); |
954 |
|
|
} while (0); |
955 |
|
|
|
956 |
|
✗ |
return ret; |
957 |
|
|
} |
958 |
|
✗ |
static gate_result_t gsvchost_remove_factory(void* this_ptr, gate_string_t const* factory_name) |
959 |
|
|
{ |
960 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
961 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
962 |
|
|
do |
963 |
|
|
{ |
964 |
|
✗ |
ret = gate_mutex_acquire(&impl->lock); |
965 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
966 |
|
✗ |
gate_map_remove(&impl->factories, factory_name); |
967 |
|
✗ |
gate_mutex_release(&impl->lock); |
968 |
|
|
} while (0); |
969 |
|
|
|
970 |
|
✗ |
return ret; |
971 |
|
|
} |
972 |
|
|
|
973 |
|
✗ |
static gate_result_t gsvchost_get_factory_service_names(void* this_ptr, gate_array_t* names) |
974 |
|
|
{ |
975 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
976 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
977 |
|
✗ |
gate_arraylist_t arr = NULL; |
978 |
|
|
|
979 |
|
|
do |
980 |
|
|
{ |
981 |
|
✗ |
arr = gate_util_map_export_keys(&impl->factories); |
982 |
|
✗ |
if (!arr) |
983 |
|
|
{ |
984 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
985 |
|
✗ |
break; |
986 |
|
|
} |
987 |
|
✗ |
if (names) |
988 |
|
|
{ |
989 |
|
✗ |
if (NULL == gate_array_create(names, arr)) |
990 |
|
|
{ |
991 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
992 |
|
✗ |
break; |
993 |
|
|
} |
994 |
|
✗ |
arr = NULL; |
995 |
|
|
} |
996 |
|
✗ |
ret = GATE_RESULT_OK; |
997 |
|
|
} while (0); |
998 |
|
|
|
999 |
|
✗ |
gate_arraylist_release(arr); |
1000 |
|
✗ |
return ret; |
1001 |
|
|
} |
1002 |
|
|
|
1003 |
|
✗ |
static gate_result_t gsvchost_create_service(void* this_ptr, |
1004 |
|
|
gate_string_t const* service_name, gate_string_t const* service_instance, gate_string_t* service_address) |
1005 |
|
|
{ |
1006 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOMATCH; |
1007 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
1008 |
|
✗ |
gate_microfactory_t* const* ptr_factory = NULL; |
1009 |
|
✗ |
gate_microfactory_t* factory = NULL; |
1010 |
|
✗ |
gate_microservice_t* service = NULL; |
1011 |
|
✗ |
gate_string_t address = GATE_STRING_INIT_EMPTY; |
1012 |
|
|
gate_map_iterator_t iter; |
1013 |
|
|
|
1014 |
|
|
do |
1015 |
|
|
{ |
1016 |
|
✗ |
ret = gate_microservice_encode_address(service_name, service_instance, &address); |
1017 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1018 |
|
|
|
1019 |
|
✗ |
if (NULL != gate_map_get(&impl->services, &address)) |
1020 |
|
|
{ |
1021 |
|
✗ |
ret = GATE_RESULT_ALREADYEXISTS; |
1022 |
|
✗ |
break; |
1023 |
|
|
} |
1024 |
|
|
|
1025 |
|
✗ |
ret = GATE_RESULT_NOMATCH; |
1026 |
|
✗ |
iter = gate_map_first(&impl->factories); |
1027 |
|
✗ |
while (gate_map_iterator_valid(iter)) |
1028 |
|
|
{ |
1029 |
|
✗ |
ptr_factory = (gate_microfactory_t* const*)gate_map_iterator_value(iter); |
1030 |
|
✗ |
if (ptr_factory) |
1031 |
|
|
{ |
1032 |
|
✗ |
factory = *ptr_factory; |
1033 |
|
✗ |
if (factory) |
1034 |
|
|
{ |
1035 |
|
✗ |
ret = gate_microfactory_create_service(factory, service_name, &service); |
1036 |
|
✗ |
if (GATE_SUCCEEDED(ret)) |
1037 |
|
|
{ |
1038 |
|
✗ |
break; |
1039 |
|
|
} |
1040 |
|
|
} |
1041 |
|
|
} |
1042 |
|
✗ |
iter = gate_map_iterator_next(iter); |
1043 |
|
|
} |
1044 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1045 |
|
|
|
1046 |
|
✗ |
if (!gate_map_add(&impl->services, &address, &service)) |
1047 |
|
|
{ |
1048 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
1049 |
|
✗ |
break; |
1050 |
|
|
} |
1051 |
|
|
|
1052 |
|
✗ |
ret = GATE_RESULT_OK; |
1053 |
|
✗ |
if (service_address) |
1054 |
|
|
{ |
1055 |
|
✗ |
gate_string_clone(service_address, &address); |
1056 |
|
|
} |
1057 |
|
|
} while (0); |
1058 |
|
|
|
1059 |
|
✗ |
gate_string_release(&address); |
1060 |
|
✗ |
if (service) |
1061 |
|
|
{ |
1062 |
|
✗ |
gate_object_release(service); |
1063 |
|
|
} |
1064 |
|
✗ |
return ret; |
1065 |
|
|
} |
1066 |
|
|
|
1067 |
|
✗ |
static gate_result_t gsvchost_get_service_addresses(void* this_ptr, gate_array_t* addresses) |
1068 |
|
|
{ |
1069 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
1070 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
1071 |
|
✗ |
gate_arraylist_t arr = NULL; |
1072 |
|
|
|
1073 |
|
|
do |
1074 |
|
|
{ |
1075 |
|
✗ |
arr = gate_util_map_export_keys(&impl->services); |
1076 |
|
✗ |
if (!arr) |
1077 |
|
|
{ |
1078 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
1079 |
|
✗ |
break; |
1080 |
|
|
} |
1081 |
|
✗ |
if (addresses) |
1082 |
|
|
{ |
1083 |
|
✗ |
if (NULL == gate_array_create(addresses, arr)) |
1084 |
|
|
{ |
1085 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
1086 |
|
✗ |
break; |
1087 |
|
|
} |
1088 |
|
|
} |
1089 |
|
✗ |
ret = GATE_RESULT_OK; |
1090 |
|
|
} while (0); |
1091 |
|
|
|
1092 |
|
✗ |
gate_arraylist_release(arr); |
1093 |
|
✗ |
return ret; |
1094 |
|
|
|
1095 |
|
|
} |
1096 |
|
|
|
1097 |
|
✗ |
static gate_result_t gsvchost_get_service(void* this_ptr, gate_string_t const* service_address, gate_microservice_t** ptr_service) |
1098 |
|
|
{ |
1099 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
1100 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
1101 |
|
✗ |
gate_microservice_t* microsvc = NULL; |
1102 |
|
✗ |
gate_microservice_t** ptr_microsvc = NULL; |
1103 |
|
|
do |
1104 |
|
|
{ |
1105 |
|
|
|
1106 |
|
✗ |
ret = gate_mutex_acquire(&impl->lock); |
1107 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1108 |
|
|
do |
1109 |
|
|
{ |
1110 |
|
✗ |
ptr_microsvc = gate_map_get_value(&impl->services, service_address); |
1111 |
|
✗ |
if (NULL == ptr_microsvc) |
1112 |
|
|
{ |
1113 |
|
✗ |
ret = GATE_RESULT_NOMATCH; |
1114 |
|
|
} |
1115 |
|
|
else |
1116 |
|
|
{ |
1117 |
|
✗ |
microsvc = *ptr_microsvc; |
1118 |
|
✗ |
if (microsvc != NULL) |
1119 |
|
|
{ |
1120 |
|
✗ |
gate_object_retain(microsvc); |
1121 |
|
✗ |
ret = GATE_RESULT_OK; |
1122 |
|
|
} |
1123 |
|
|
else |
1124 |
|
|
{ |
1125 |
|
✗ |
ret = GATE_RESULT_NULLPOINTER; |
1126 |
|
|
} |
1127 |
|
|
} |
1128 |
|
|
} while (0); |
1129 |
|
✗ |
gate_mutex_release(&impl->lock); |
1130 |
|
|
|
1131 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1132 |
|
|
|
1133 |
|
✗ |
if (ptr_service != NULL) |
1134 |
|
|
{ |
1135 |
|
✗ |
*ptr_service = microsvc; |
1136 |
|
✗ |
microsvc = NULL; |
1137 |
|
|
} |
1138 |
|
|
} while (0); |
1139 |
|
|
|
1140 |
|
✗ |
if (microsvc != NULL) |
1141 |
|
|
{ |
1142 |
|
✗ |
gate_object_release(microsvc); |
1143 |
|
|
} |
1144 |
|
|
|
1145 |
|
✗ |
return ret; |
1146 |
|
|
} |
1147 |
|
|
|
1148 |
|
✗ |
static gate_result_t gsvchost_get_service_config(void* this_ptr, gate_string_t const* service_address, gate_uint32_t config_type, gate_value_t* value) |
1149 |
|
|
{ |
1150 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
1151 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
1152 |
|
|
|
1153 |
|
|
gate_map_iterator_t iter; |
1154 |
|
|
gate_map_t const* ptr_map; |
1155 |
|
|
gate_value_t const* ptr_value; |
1156 |
|
|
|
1157 |
|
|
do |
1158 |
|
|
{ |
1159 |
|
✗ |
iter = gate_map_get(&impl->services_configs, service_address); |
1160 |
|
✗ |
if (!gate_map_iterator_valid(iter)) |
1161 |
|
|
{ |
1162 |
|
✗ |
break; |
1163 |
|
|
} |
1164 |
|
✗ |
ptr_map = (gate_map_t const*)gate_map_iterator_value(iter); |
1165 |
|
✗ |
if (!ptr_map) |
1166 |
|
|
{ |
1167 |
|
✗ |
break; |
1168 |
|
|
} |
1169 |
|
✗ |
iter = gate_map_get(ptr_map, &config_type); |
1170 |
|
✗ |
if (!gate_map_iterator_valid(iter)) |
1171 |
|
|
{ |
1172 |
|
✗ |
break; |
1173 |
|
|
} |
1174 |
|
✗ |
ptr_value = (gate_value_t const*)gate_map_iterator_value(iter); |
1175 |
|
✗ |
if (!ptr_value) |
1176 |
|
|
{ |
1177 |
|
✗ |
break; |
1178 |
|
|
} |
1179 |
|
✗ |
if (NULL == gate_value_clone(ptr_value, value)) |
1180 |
|
|
{ |
1181 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
1182 |
|
✗ |
break; |
1183 |
|
|
} |
1184 |
|
✗ |
ret = GATE_RESULT_OK; |
1185 |
|
|
} while (0); |
1186 |
|
|
|
1187 |
|
✗ |
return ret; |
1188 |
|
|
} |
1189 |
|
|
|
1190 |
|
✗ |
static gate_result_t gsvchost_set_service_config(void* this_ptr, gate_string_t const* service_address, gate_uint32_t config_type, gate_value_t const* value) |
1191 |
|
|
{ |
1192 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
1193 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
1194 |
|
|
|
1195 |
|
|
gate_map_iterator_t iter; |
1196 |
|
✗ |
gate_map_t tmp = GATE_INIT_EMPTY; |
1197 |
|
✗ |
gate_map_t* ptr_map = NULL; |
1198 |
|
|
|
1199 |
|
|
do |
1200 |
|
|
{ |
1201 |
|
✗ |
iter = gate_map_get(&impl->services_configs, service_address); |
1202 |
|
✗ |
if (!gate_map_iterator_valid(iter)) |
1203 |
|
|
{ |
1204 |
|
✗ |
gate_map_create(&tmp, gate_compare_uint32, sizeof(gate_uint32_t), NULL, NULL, |
1205 |
|
|
sizeof(gate_value_t), &gate_value_copy_constructor, &gate_value_destructor); |
1206 |
|
✗ |
iter = gate_map_add(&tmp, &config_type, value); |
1207 |
|
✗ |
if (!gate_map_iterator_valid(iter)) |
1208 |
|
|
{ |
1209 |
|
✗ |
gate_map_destroy(&tmp); |
1210 |
|
✗ |
break; |
1211 |
|
|
} |
1212 |
|
✗ |
iter = gate_map_add(&impl->services_configs, service_address, &tmp); |
1213 |
|
✗ |
gate_map_destroy(&tmp); |
1214 |
|
✗ |
if (gate_map_iterator_valid(iter)) |
1215 |
|
|
{ |
1216 |
|
✗ |
ret = GATE_RESULT_OK; |
1217 |
|
|
} |
1218 |
|
|
} |
1219 |
|
|
else |
1220 |
|
|
{ |
1221 |
|
✗ |
ptr_map = (gate_map_t*)gate_map_iterator_value(iter); |
1222 |
|
✗ |
if (!ptr_map) |
1223 |
|
|
{ |
1224 |
|
✗ |
break; |
1225 |
|
|
} |
1226 |
|
✗ |
iter = gate_map_add(ptr_map, &config_type, value); |
1227 |
|
✗ |
if (gate_map_iterator_valid(iter)) |
1228 |
|
|
{ |
1229 |
|
✗ |
ret = GATE_RESULT_OK; |
1230 |
|
|
} |
1231 |
|
|
} |
1232 |
|
|
|
1233 |
|
|
} while (0); |
1234 |
|
|
|
1235 |
|
✗ |
return ret; |
1236 |
|
|
} |
1237 |
|
|
|
1238 |
|
|
|
1239 |
|
✗ |
static gate_result_t gsvchost_start_service(void* this_ptr, gate_string_t const* service_address) |
1240 |
|
|
{ |
1241 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
1242 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
1243 |
|
✗ |
gate_microservice_t* service = NULL; |
1244 |
|
|
|
1245 |
|
|
do |
1246 |
|
|
{ |
1247 |
|
✗ |
ret = gsvchost_get_service(this_ptr, service_address, &service); |
1248 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1249 |
|
✗ |
ret = gate_microservice_setup(service, service_address, ((gate_microhost_t*)impl)); |
1250 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1251 |
|
✗ |
ret = gate_microservice_start(service); |
1252 |
|
|
} while (0); |
1253 |
|
|
|
1254 |
|
✗ |
if (service != NULL) |
1255 |
|
|
{ |
1256 |
|
✗ |
gate_object_release(service); |
1257 |
|
|
} |
1258 |
|
|
|
1259 |
|
✗ |
return ret; |
1260 |
|
|
} |
1261 |
|
✗ |
static gate_result_t gsvchost_stop_service(void* this_ptr, gate_string_t const* service_address) |
1262 |
|
|
{ |
1263 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
1264 |
|
✗ |
gate_microservice_t* service = NULL; |
1265 |
|
|
|
1266 |
|
|
do |
1267 |
|
|
{ |
1268 |
|
✗ |
ret = gsvchost_get_service(this_ptr, service_address, &service); |
1269 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1270 |
|
✗ |
ret = gate_microservice_stop(service); |
1271 |
|
|
} while (0); |
1272 |
|
|
|
1273 |
|
✗ |
if (service != NULL) |
1274 |
|
|
{ |
1275 |
|
✗ |
gate_object_release(service); |
1276 |
|
|
} |
1277 |
|
|
|
1278 |
|
✗ |
return ret; |
1279 |
|
|
} |
1280 |
|
|
|
1281 |
|
|
|
1282 |
|
✗ |
static gate_bool_t gsvchost_remove_subscription_by_pointer(void const* item, void* param) |
1283 |
|
|
{ |
1284 |
|
✗ |
subscription_t const* subscr = (subscription_t const*)item; |
1285 |
|
✗ |
gate_microservice_t* service = (gate_microservice_t*)param; |
1286 |
|
|
|
1287 |
|
✗ |
return subscr->service == service; |
1288 |
|
|
} |
1289 |
|
|
|
1290 |
|
✗ |
static gate_bool_t gsvchost_remove_subscription_by_name(void const* item, void* param) |
1291 |
|
|
{ |
1292 |
|
✗ |
subscription_t const* subscr = (subscription_t const*)item; |
1293 |
|
✗ |
gate_string_t const* name = (gate_string_t const*)param; |
1294 |
|
|
|
1295 |
|
✗ |
return gate_string_equals(&subscr->destination_address, name); |
1296 |
|
|
} |
1297 |
|
|
|
1298 |
|
|
|
1299 |
|
✗ |
static gate_result_t gsvchost_remove_service(void* this_ptr, gate_string_t const* service_address) |
1300 |
|
|
{ |
1301 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
1302 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
1303 |
|
✗ |
gate_microservice_t* microsvc = NULL; |
1304 |
|
✗ |
gate_microservice_t** ptr_microsvc = NULL; |
1305 |
|
|
do |
1306 |
|
|
{ |
1307 |
|
|
|
1308 |
|
✗ |
ret = gate_mutex_acquire(&impl->lock); |
1309 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1310 |
|
|
do |
1311 |
|
|
{ |
1312 |
|
✗ |
ptr_microsvc = gate_map_get_value(&impl->services, service_address); |
1313 |
|
✗ |
if (NULL == ptr_microsvc) |
1314 |
|
|
{ |
1315 |
|
✗ |
ret = GATE_RESULT_NOMATCH; |
1316 |
|
|
} |
1317 |
|
|
else |
1318 |
|
|
{ |
1319 |
|
✗ |
microsvc = *ptr_microsvc; |
1320 |
|
✗ |
if (microsvc != NULL) |
1321 |
|
|
{ |
1322 |
|
✗ |
gate_object_retain(microsvc); |
1323 |
|
✗ |
ret = GATE_RESULT_OK; |
1324 |
|
|
|
1325 |
|
✗ |
gate_arraylist_remove_if(impl->msg_subscriptions, &gsvchost_remove_subscription_by_pointer, microsvc); |
1326 |
|
✗ |
gate_arraylist_remove_if(impl->msg_subscriptions, &gsvchost_remove_subscription_by_name, (void*)service_address); |
1327 |
|
✗ |
gate_arraylist_remove_if(impl->obj_subscriptions, &gsvchost_remove_subscription_by_pointer, microsvc); |
1328 |
|
✗ |
gate_arraylist_remove_if(impl->obj_subscriptions, &gsvchost_remove_subscription_by_name, (void*)service_address); |
1329 |
|
|
} |
1330 |
|
|
else |
1331 |
|
|
{ |
1332 |
|
✗ |
ret = GATE_RESULT_NULLPOINTER; |
1333 |
|
|
} |
1334 |
|
✗ |
gate_map_remove(&impl->services, service_address); |
1335 |
|
|
} |
1336 |
|
|
} while (0); |
1337 |
|
✗ |
gate_mutex_release(&impl->lock); |
1338 |
|
|
|
1339 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1340 |
|
|
|
1341 |
|
|
} while (0); |
1342 |
|
|
|
1343 |
|
✗ |
if (microsvc != NULL) |
1344 |
|
|
{ |
1345 |
|
✗ |
gate_microservice_stop(microsvc); |
1346 |
|
✗ |
gate_object_release(microsvc); |
1347 |
|
|
} |
1348 |
|
|
|
1349 |
|
✗ |
return ret; |
1350 |
|
|
} |
1351 |
|
|
|
1352 |
|
✗ |
static gate_size_t gsvchost_start_services(gate_servicehost_impl_t* host, |
1353 |
|
|
gate_string_t const* const* addresses, gate_size_t addresses_count) |
1354 |
|
|
{ |
1355 |
|
✗ |
gate_size_t started_counter = 0; |
1356 |
|
|
gate_microservice_t* ptr_service; |
1357 |
|
|
gate_result_t result; |
1358 |
|
|
|
1359 |
|
✗ |
while (addresses_count-- != 0) |
1360 |
|
|
{ |
1361 |
|
✗ |
result = gate_servicehost_get_service(host, *addresses, &ptr_service); |
1362 |
|
✗ |
if (GATE_SUCCEEDED(result)) |
1363 |
|
|
{ |
1364 |
|
✗ |
result = gate_microservice_setup(ptr_service, *addresses, (gate_microhost_t*)host); |
1365 |
|
✗ |
if (GATE_SUCCEEDED(result)) |
1366 |
|
|
{ |
1367 |
|
✗ |
result = gate_microservice_start(ptr_service); |
1368 |
|
✗ |
if (GATE_SUCCEEDED(result)) |
1369 |
|
|
{ |
1370 |
|
✗ |
++started_counter; |
1371 |
|
|
} |
1372 |
|
|
} |
1373 |
|
✗ |
gate_object_release(ptr_service); |
1374 |
|
|
} |
1375 |
|
✗ |
++addresses; |
1376 |
|
|
} |
1377 |
|
✗ |
return started_counter; |
1378 |
|
|
} |
1379 |
|
|
|
1380 |
|
✗ |
static gate_size_t gsvchost_stop_services(gate_servicehost_impl_t* host, |
1381 |
|
|
gate_string_t const* const* addresses, gate_size_t addresses_count) |
1382 |
|
|
{ |
1383 |
|
✗ |
gate_size_t started_counter = 0; |
1384 |
|
|
gate_microservice_t* ptr_service; |
1385 |
|
|
gate_result_t result; |
1386 |
|
|
|
1387 |
|
✗ |
while (addresses_count-- != 0) |
1388 |
|
|
{ |
1389 |
|
✗ |
result = gate_servicehost_get_service(host, *addresses, &ptr_service); |
1390 |
|
✗ |
if (GATE_SUCCEEDED(result)) |
1391 |
|
|
{ |
1392 |
|
✗ |
result = gate_microservice_stop(ptr_service); |
1393 |
|
✗ |
if (GATE_SUCCEEDED(result)) |
1394 |
|
|
{ |
1395 |
|
✗ |
++started_counter; |
1396 |
|
|
} |
1397 |
|
✗ |
gate_object_release(ptr_service); |
1398 |
|
|
} |
1399 |
|
✗ |
++addresses; |
1400 |
|
|
} |
1401 |
|
✗ |
return started_counter; |
1402 |
|
|
} |
1403 |
|
|
|
1404 |
|
✗ |
static void gsvchost_release_services(gate_servicehost_impl_t* host, |
1405 |
|
|
gate_string_t const* const* addresses, gate_size_t addresses_count) |
1406 |
|
|
{ |
1407 |
|
✗ |
while (addresses_count-- != 0) |
1408 |
|
|
{ |
1409 |
|
✗ |
gate_servicehost_release_service(host, *addresses); |
1410 |
|
✗ |
++addresses; |
1411 |
|
|
} |
1412 |
|
✗ |
} |
1413 |
|
|
|
1414 |
|
|
|
1415 |
|
✗ |
static gate_result_t gsvchost_start_up(void* this_ptr) |
1416 |
|
|
{ |
1417 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
1418 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
1419 |
|
|
|
1420 |
|
✗ |
gate_array_t addresses = GATE_INIT_EMPTY; |
1421 |
|
|
gate_size_t index; |
1422 |
|
|
gate_size_t length; |
1423 |
|
|
gate_string_t const* addresses_to_start[1024]; |
1424 |
|
✗ |
gate_size_t const addresses_max = sizeof(addresses_to_start) / sizeof(addresses_to_start[0]); |
1425 |
|
✗ |
gate_size_t addresses_to_start_count = 0; |
1426 |
|
|
gate_string_t const* ptr_address; |
1427 |
|
|
gate_bool_t autostart_enabled; |
1428 |
|
✗ |
gate_value_t value_autostart_enabled = GATE_INIT_EMPTY; |
1429 |
|
|
gate_result_t result; |
1430 |
|
|
|
1431 |
|
|
do |
1432 |
|
|
{ |
1433 |
|
✗ |
ret = gate_servicehost_get_service_addresses(impl, &addresses); |
1434 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1435 |
|
|
|
1436 |
|
✗ |
length = gate_array_length(&addresses); |
1437 |
|
✗ |
for (index = 0; index != length; ++index) |
1438 |
|
|
{ |
1439 |
|
✗ |
ptr_address = (gate_string_t const*)gate_array_get(&addresses, index); |
1440 |
|
✗ |
if (ptr_address) |
1441 |
|
|
{ |
1442 |
|
✗ |
autostart_enabled = false; |
1443 |
|
✗ |
result = gate_servicehost_get_service_config(impl, ptr_address, |
1444 |
|
|
GATE_SERVICEHOST_CONFIG_AUTOSTART, |
1445 |
|
|
&value_autostart_enabled); |
1446 |
|
✗ |
if (GATE_SUCCEEDED(result)) |
1447 |
|
|
{ |
1448 |
|
✗ |
gate_value_get(&value_autostart_enabled, &autostart_enabled, sizeof(autostart_enabled)); |
1449 |
|
|
} |
1450 |
|
|
|
1451 |
|
✗ |
if (autostart_enabled) |
1452 |
|
|
{ |
1453 |
|
✗ |
addresses_to_start[addresses_to_start_count++] = ptr_address; |
1454 |
|
✗ |
if (addresses_to_start_count >= addresses_max) |
1455 |
|
|
{ |
1456 |
|
✗ |
break; |
1457 |
|
|
} |
1458 |
|
|
} |
1459 |
|
|
} |
1460 |
|
|
} |
1461 |
|
✗ |
gsvchost_start_services(impl, addresses_to_start, addresses_to_start_count); |
1462 |
|
|
} while (0); |
1463 |
|
|
|
1464 |
|
✗ |
gate_array_release(&addresses); |
1465 |
|
|
|
1466 |
|
✗ |
return ret; |
1467 |
|
|
} |
1468 |
|
✗ |
static gate_result_t gsvchost_shut_down(void* this_ptr, gate_bool_t release_services) |
1469 |
|
|
{ |
1470 |
|
✗ |
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
1471 |
|
✗ |
gate_servicehost_impl_t* impl = (gate_servicehost_impl_t*)this_ptr; |
1472 |
|
|
|
1473 |
|
✗ |
gate_array_t addresses = GATE_INIT_EMPTY; |
1474 |
|
|
gate_size_t index; |
1475 |
|
|
gate_size_t length; |
1476 |
|
|
gate_string_t const* addresses_to_stop[512]; |
1477 |
|
✗ |
gate_size_t const addresses_max = sizeof(addresses_to_stop) / sizeof(addresses_to_stop[0]); |
1478 |
|
✗ |
gate_size_t addresses_to_stop_count = 0; |
1479 |
|
|
gate_string_t const* ptr_address; |
1480 |
|
|
|
1481 |
|
|
do |
1482 |
|
|
{ |
1483 |
|
✗ |
ret = gate_servicehost_get_service_addresses(impl, &addresses); |
1484 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1485 |
|
|
|
1486 |
|
✗ |
length = gate_array_length(&addresses); |
1487 |
|
✗ |
for (index = 0; index != length; ++index) |
1488 |
|
|
{ |
1489 |
|
✗ |
ptr_address = (gate_string_t const*)gate_array_get(&addresses, index); |
1490 |
|
✗ |
if (ptr_address) |
1491 |
|
|
{ |
1492 |
|
✗ |
addresses_to_stop[addresses_to_stop_count++] = ptr_address; |
1493 |
|
✗ |
if (addresses_to_stop_count >= addresses_max) |
1494 |
|
|
{ |
1495 |
|
✗ |
break; |
1496 |
|
|
} |
1497 |
|
|
} |
1498 |
|
|
} |
1499 |
|
✗ |
gsvchost_stop_services(impl, addresses_to_stop, addresses_to_stop_count); |
1500 |
|
✗ |
if (release_services) |
1501 |
|
|
{ |
1502 |
|
✗ |
gsvchost_release_services(impl, addresses_to_stop, addresses_to_stop_count); |
1503 |
|
|
} |
1504 |
|
|
} while (0); |
1505 |
|
|
|
1506 |
|
✗ |
gate_array_release(&addresses); |
1507 |
|
|
|
1508 |
|
✗ |
return ret; |
1509 |
|
|
} |
1510 |
|
|
|
1511 |
|
|
|
1512 |
|
|
static GATE_INTERFACE_VTBL(gate_servicehost) gate_servicehost_vtbl; |
1513 |
|
✗ |
static void gate_init_servicehost_vtbl() |
1514 |
|
|
{ |
1515 |
|
✗ |
if (!gate_servicehost_vtbl.get_interface_name) |
1516 |
|
|
{ |
1517 |
|
|
GATE_INTERFACE_VTBL(gate_servicehost) const local_vtbl = |
1518 |
|
|
{ |
1519 |
|
|
&gsvchost_get_interface_name, |
1520 |
|
|
&gsvchost_release, |
1521 |
|
|
&gsvchost_retain, |
1522 |
|
|
|
1523 |
|
|
&gsvchost_publish_message, |
1524 |
|
|
&gsvchost_publish_object, |
1525 |
|
|
|
1526 |
|
|
&gsvchost_subscribe_messages, |
1527 |
|
|
&gsvchost_unsubscribe_messages, |
1528 |
|
|
|
1529 |
|
|
&gsvchost_subscribe_objects, |
1530 |
|
|
&gsvchost_unsubscribe_objects, |
1531 |
|
|
|
1532 |
|
|
&gsvchost_remote_invoke, |
1533 |
|
|
|
1534 |
|
|
&gsvchost_log, |
1535 |
|
|
|
1536 |
|
|
&gsvchost_add_factory, |
1537 |
|
|
&gsvchost_remove_factory, |
1538 |
|
|
&gsvchost_get_factory_service_names, |
1539 |
|
|
|
1540 |
|
|
&gsvchost_create_service, |
1541 |
|
|
&gsvchost_get_service_addresses, |
1542 |
|
|
&gsvchost_get_service, |
1543 |
|
|
&gsvchost_get_service_config, |
1544 |
|
|
&gsvchost_set_service_config, |
1545 |
|
|
&gsvchost_start_service, |
1546 |
|
|
&gsvchost_stop_service, |
1547 |
|
|
&gsvchost_remove_service, |
1548 |
|
|
|
1549 |
|
|
&gsvchost_start_up, |
1550 |
|
|
&gsvchost_shut_down |
1551 |
|
|
}; |
1552 |
|
✗ |
gate_servicehost_vtbl = local_vtbl; |
1553 |
|
|
} |
1554 |
|
✗ |
} |
1555 |
|
|
|
1556 |
|
|
|
1557 |
|
✗ |
gate_servicehost_t* gate_servicehost_create() |
1558 |
|
|
{ |
1559 |
|
✗ |
gate_servicehost_t* ret = NULL; |
1560 |
|
✗ |
gate_servicehost_impl_t* impl = NULL; |
1561 |
|
|
do |
1562 |
|
|
{ |
1563 |
|
✗ |
impl = (gate_servicehost_impl_t*)gate_mem_alloc(sizeof(gate_servicehost_impl_t)); |
1564 |
|
✗ |
if (impl == NULL) |
1565 |
|
|
{ |
1566 |
|
✗ |
break; |
1567 |
|
|
} |
1568 |
|
|
|
1569 |
|
✗ |
if (GATE_SUCCEEDED(gsvchost_init_members(impl))) |
1570 |
|
|
{ |
1571 |
|
✗ |
gate_init_servicehost_vtbl(); |
1572 |
|
✗ |
impl->vtbl = &gate_servicehost_vtbl; |
1573 |
|
✗ |
ret = (gate_servicehost_t*)impl; |
1574 |
|
✗ |
impl = NULL; |
1575 |
|
|
} |
1576 |
|
|
|
1577 |
|
|
} while (0); |
1578 |
|
|
|
1579 |
|
✗ |
if (impl != NULL) |
1580 |
|
|
{ |
1581 |
|
✗ |
gsvchost_destroy(impl); |
1582 |
|
|
} |
1583 |
|
|
|
1584 |
|
✗ |
return ret; |
1585 |
|
|
} |
1586 |
|
|
|
1587 |
|
|
|
1588 |
|
✗ |
gate_result_t gate_servicehost_load_config(gate_stream_t* srcstream, gate_uint32_t format, gate_servicehost_config_t* ptr_config) |
1589 |
|
|
{ |
1590 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
1591 |
|
✗ |
gate_property_t prop = GATE_INIT_EMPTY; |
1592 |
|
✗ |
gate_yaml_result_t yaml_result = GATE_INIT_EMPTY; |
1593 |
|
✗ |
gate_json_result_t json_result = GATE_INIT_EMPTY; |
1594 |
|
|
|
1595 |
|
|
do |
1596 |
|
|
{ |
1597 |
|
✗ |
if (format == GATE_SERVICEHOST_CONFIG_FORMAT_YAML) |
1598 |
|
|
{ |
1599 |
|
✗ |
ret = gate_yaml_parse(srcstream, &prop, &yaml_result); |
1600 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1601 |
|
✗ |
if (!yaml_result.succeeded) |
1602 |
|
|
{ |
1603 |
|
✗ |
ret = GATE_RESULT_INVALIDCONTENT; |
1604 |
|
✗ |
break; |
1605 |
|
|
} |
1606 |
|
|
} |
1607 |
|
✗ |
else if (format == GATE_SERVICEHOST_CONFIG_FORMAT_YAML) |
1608 |
|
|
{ |
1609 |
|
✗ |
ret = gate_json_parse(srcstream, &prop, &json_result); |
1610 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1611 |
|
✗ |
if (!json_result.succeeded) |
1612 |
|
|
{ |
1613 |
|
✗ |
ret = GATE_RESULT_INVALIDCONTENT; |
1614 |
|
✗ |
break; |
1615 |
|
|
} |
1616 |
|
|
} |
1617 |
|
|
else |
1618 |
|
|
{ |
1619 |
|
✗ |
ret = GATE_RESULT_INVALIDARG; |
1620 |
|
✗ |
break; |
1621 |
|
|
} |
1622 |
|
|
|
1623 |
|
✗ |
if (gate_property_get_type(&prop) != GATE_PROPERTY_TYPE_OBJECT) |
1624 |
|
|
{ |
1625 |
|
✗ |
ret = GATE_RESULT_INVALIDDATA; |
1626 |
|
✗ |
break; |
1627 |
|
|
} |
1628 |
|
|
|
1629 |
|
✗ |
ret = gate_servicehost_config_init(&ptr_config->struct_base); |
1630 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1631 |
|
|
|
1632 |
|
✗ |
ret = gate_property_export(&prop, GATE_TYPE_STRUCT, &ptr_config->struct_base); |
1633 |
|
|
} while (0); |
1634 |
|
|
|
1635 |
|
✗ |
gate_property_destroy(&prop); |
1636 |
|
|
|
1637 |
|
✗ |
return ret; |
1638 |
|
|
} |
1639 |
|
✗ |
gate_result_t gate_servicehost_save_config(gate_servicehost_config_t const* config, gate_uint32_t format, gate_stream_t* deststream) |
1640 |
|
|
{ |
1641 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
1642 |
|
✗ |
gate_property_t prop = GATE_INIT_EMPTY; |
1643 |
|
|
|
1644 |
|
|
do |
1645 |
|
|
{ |
1646 |
|
✗ |
ret = gate_property_import(&prop, GATE_TYPE_STRUCT, &config->struct_base); |
1647 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1648 |
|
|
|
1649 |
|
✗ |
if (format == GATE_SERVICEHOST_CONFIG_FORMAT_YAML) |
1650 |
|
|
{ |
1651 |
|
✗ |
ret = gate_yaml_build(&prop, deststream); |
1652 |
|
✗ |
break; |
1653 |
|
|
} |
1654 |
|
✗ |
else if (format == GATE_SERVICEHOST_CONFIG_FORMAT_JSON) |
1655 |
|
|
{ |
1656 |
|
✗ |
ret = gate_json_build(&prop, deststream, 2); |
1657 |
|
|
} |
1658 |
|
|
else |
1659 |
|
|
{ |
1660 |
|
✗ |
ret = GATE_RESULT_INVALIDARG; |
1661 |
|
✗ |
break; |
1662 |
|
|
} |
1663 |
|
|
|
1664 |
|
|
} while (0); |
1665 |
|
|
|
1666 |
|
✗ |
gate_property_destroy(&prop); |
1667 |
|
|
|
1668 |
|
✗ |
return ret; |
1669 |
|
|
} |
1670 |
|
|
|
1671 |
|
✗ |
gate_result_t gate_servicehost_import_config(gate_servicehost_t* host, gate_servicehost_config_t const* config) |
1672 |
|
|
{ |
1673 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
1674 |
|
|
gate_size_t index, name_ndx, name_count; |
1675 |
|
✗ |
gate_size_t count = gate_arraylist_length(config->services); |
1676 |
|
|
gate_servicehost_config_service_t const* ptr_svc; |
1677 |
|
✗ |
gate_string_t address = GATE_STRING_INIT_EMPTY; |
1678 |
|
✗ |
gate_microservice_t* ptr_microsvc = NULL; |
1679 |
|
✗ |
gate_array_t param_names = GATE_INIT_EMPTY; |
1680 |
|
|
gate_string_t const* ptr_name; |
1681 |
|
|
gate_property_t const* ptr_param_prop; |
1682 |
|
|
gate_size_t subscr_count; |
1683 |
|
|
gate_size_t subscr_index; |
1684 |
|
|
gate_string_t const* subscr_str; |
1685 |
|
✗ |
gate_string_t subscr_id = GATE_STRING_INIT_EMPTY; |
1686 |
|
✗ |
gate_string_t subscr_addr = GATE_STRING_INIT_EMPTY; |
1687 |
|
|
gate_size_t subscr_pos; |
1688 |
|
|
gate_value_t cfg_value; |
1689 |
|
|
|
1690 |
|
✗ |
for (index = 0; index != count; ++index) |
1691 |
|
|
{ |
1692 |
|
✗ |
ptr_svc = (gate_servicehost_config_service_t const*)gate_arraylist_get(config->services, index); |
1693 |
|
✗ |
if (ptr_svc) |
1694 |
|
|
{ |
1695 |
|
✗ |
ret = gate_servicehost_create_service(host, &ptr_svc->name, &ptr_svc->instance, &address); |
1696 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1697 |
|
✗ |
ret = gate_servicehost_get_service(host, &address, &ptr_microsvc); |
1698 |
|
✗ |
if (GATE_SUCCEEDED(ret)) |
1699 |
|
|
{ |
1700 |
|
✗ |
if (gate_property_get_type(&ptr_svc->parameters) == GATE_PROPERTY_TYPE_OBJECT) |
1701 |
|
|
{ |
1702 |
|
✗ |
if (NULL == gate_property_member_names(&ptr_svc->parameters, ¶m_names)) |
1703 |
|
|
{ |
1704 |
|
✗ |
ret = GATE_RESULT_OUTOFMEMORY; |
1705 |
|
✗ |
break; |
1706 |
|
|
} |
1707 |
|
|
|
1708 |
|
✗ |
name_count = gate_array_length(¶m_names); |
1709 |
|
✗ |
for (name_ndx = 0; name_ndx != name_count; ++name_ndx) |
1710 |
|
|
{ |
1711 |
|
✗ |
ptr_name = (gate_string_t const*)gate_array_get(¶m_names, name_ndx); |
1712 |
|
✗ |
if (ptr_name) |
1713 |
|
|
{ |
1714 |
|
✗ |
ptr_param_prop = gate_property_member_get(&ptr_svc->parameters, ptr_name); |
1715 |
|
✗ |
if (ptr_param_prop) |
1716 |
|
|
{ |
1717 |
|
✗ |
ret = gate_microservice_set_parameter(ptr_microsvc, ptr_name, ptr_param_prop); |
1718 |
|
|
} |
1719 |
|
|
} |
1720 |
|
|
} |
1721 |
|
✗ |
gate_array_release(¶m_names); |
1722 |
|
|
} |
1723 |
|
✗ |
subscr_count = gate_arraylist_length(ptr_svc->msg_subscriptions); |
1724 |
|
✗ |
for (subscr_index = 0; subscr_index != subscr_count; ++subscr_index) |
1725 |
|
|
{ |
1726 |
|
✗ |
subscr_str = (gate_string_t const*)gate_arraylist_get(ptr_svc->msg_subscriptions, subscr_index); |
1727 |
|
✗ |
if (subscr_str) |
1728 |
|
|
{ |
1729 |
|
✗ |
subscr_pos = gate_string_char_pos(subscr_str, ':', 0); |
1730 |
|
✗ |
if (subscr_pos == GATE_STR_NPOS) |
1731 |
|
|
{ |
1732 |
|
✗ |
gate_servicehost_subscribe_messages(host, subscr_str, &address, NULL, ptr_microsvc, NULL); |
1733 |
|
|
} |
1734 |
|
|
else |
1735 |
|
|
{ |
1736 |
|
✗ |
gate_string_substr(&subscr_addr, subscr_str, 0, subscr_pos); |
1737 |
|
✗ |
gate_string_substr(&subscr_id, subscr_str, subscr_pos + 1, GATE_STR_NPOS); |
1738 |
|
✗ |
gate_servicehost_subscribe_messages(host, &subscr_addr, &address, &subscr_id, ptr_microsvc, NULL); |
1739 |
|
✗ |
gate_string_release(&subscr_id); |
1740 |
|
✗ |
gate_string_release(&subscr_addr); |
1741 |
|
|
} |
1742 |
|
|
} |
1743 |
|
|
} |
1744 |
|
|
|
1745 |
|
|
/* inject advanced configuration values */ |
1746 |
|
✗ |
if (gate_value_create(GATE_TYPE_BOOL, &ptr_svc->autostart, &cfg_value)) |
1747 |
|
|
{ |
1748 |
|
✗ |
gate_servicehost_set_service_config(host, &address, GATE_SERVICEHOST_CONFIG_AUTOSTART, &cfg_value); |
1749 |
|
✗ |
gate_value_release(&cfg_value); |
1750 |
|
|
} |
1751 |
|
✗ |
if (gate_value_create(GATE_TYPE_UI32, &ptr_svc->startorder, &cfg_value)) |
1752 |
|
|
{ |
1753 |
|
✗ |
gate_servicehost_set_service_config(host, &address, GATE_SERVICEHOST_CONFIG_STARTORDER, &cfg_value); |
1754 |
|
✗ |
gate_value_release(&cfg_value); |
1755 |
|
|
} |
1756 |
|
✗ |
if (gate_value_create(GATE_TYPE_STRING, &ptr_svc->service_group, &cfg_value)) |
1757 |
|
|
{ |
1758 |
|
✗ |
gate_servicehost_set_service_config(host, &address, GATE_SERVICEHOST_CONFIG_SERVICEGROUP, &cfg_value); |
1759 |
|
✗ |
gate_value_release(&cfg_value); |
1760 |
|
|
} |
1761 |
|
|
} |
1762 |
|
✗ |
if (NULL != ptr_microsvc) |
1763 |
|
|
{ |
1764 |
|
✗ |
gate_object_release(ptr_microsvc); |
1765 |
|
|
} |
1766 |
|
|
|
1767 |
|
|
|
1768 |
|
✗ |
gate_string_release(&address); |
1769 |
|
|
} |
1770 |
|
✗ |
ret = GATE_RESULT_OK; |
1771 |
|
|
} |
1772 |
|
|
|
1773 |
|
✗ |
gate_string_release(&address); |
1774 |
|
✗ |
return ret; |
1775 |
|
|
} |
1776 |
|
|
|
1777 |
|
|
static const gate_string_t default_servicehost_config_id = GATE_STRING_INIT_STATIC("gate/microservices/config"); |
1778 |
|
|
static const gate_string_t default_servicehost_config_version = GATE_STRING_INIT_STATIC("1.0"); |
1779 |
|
|
|
1780 |
|
✗ |
gate_result_t gate_servicehost_export_config(gate_servicehost_t* host, gate_servicehost_config_t* config) |
1781 |
|
|
{ |
1782 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
1783 |
|
✗ |
gate_array_t addresses = GATE_INIT_EMPTY; |
1784 |
|
|
gate_size_t ndx, length; |
1785 |
|
|
gate_string_t const* ptr_str; |
1786 |
|
✗ |
gate_microservice_t* ptr_svc = NULL; |
1787 |
|
✗ |
gate_array_t param_names = GATE_INIT_EMPTY; |
1788 |
|
|
gate_string_t const* ptr_param_name; |
1789 |
|
|
gate_property_t prop; |
1790 |
|
|
gate_size_t name_index, name_count; |
1791 |
|
|
gate_property_t service_params; |
1792 |
|
✗ |
gate_string_t str_name = GATE_STRING_INIT_EMPTY; |
1793 |
|
✗ |
gate_string_t str_instance = GATE_STRING_INIT_EMPTY; |
1794 |
|
|
gate_servicehost_config_service_t cfg_svc; |
1795 |
|
|
|
1796 |
|
|
do |
1797 |
|
|
{ |
1798 |
|
✗ |
ret = gate_servicehost_get_service_addresses(host, &addresses); |
1799 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1800 |
|
|
|
1801 |
|
✗ |
ret = gate_servicehost_config_init(&config->struct_base); |
1802 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
1803 |
|
|
|
1804 |
|
✗ |
gate_string_duplicate(&config->id, &default_servicehost_config_id); |
1805 |
|
✗ |
gate_string_duplicate(&config->version, &default_servicehost_config_version); |
1806 |
|
|
|
1807 |
|
✗ |
length = gate_array_length(&addresses); |
1808 |
|
✗ |
for (ndx = 0; ndx != length; ++ndx) |
1809 |
|
|
{ |
1810 |
|
✗ |
if (ptr_svc != NULL) |
1811 |
|
|
{ |
1812 |
|
✗ |
gate_object_release(ptr_svc); |
1813 |
|
✗ |
ptr_svc = NULL; |
1814 |
|
|
} |
1815 |
|
|
|
1816 |
|
✗ |
ptr_str = (gate_string_t const*)gate_array_get(&addresses, ndx); |
1817 |
|
✗ |
if (!ptr_str) |
1818 |
|
|
{ |
1819 |
|
✗ |
continue; |
1820 |
|
|
} |
1821 |
|
✗ |
ret = gate_servicehost_get_service(host, ptr_str, &ptr_svc); |
1822 |
|
✗ |
if (GATE_FAILED(ret)) |
1823 |
|
|
{ |
1824 |
|
✗ |
continue; |
1825 |
|
|
} |
1826 |
|
|
|
1827 |
|
✗ |
ret = gate_servicehost_config_service_init(&cfg_svc.struct_base); |
1828 |
|
|
|
1829 |
|
✗ |
if (GATE_SUCCEEDED(ret)) |
1830 |
|
|
{ |
1831 |
|
✗ |
gate_string_duplicate(&cfg_svc.name, &str_name); |
1832 |
|
✗ |
gate_string_duplicate(&cfg_svc.instance, &str_instance); |
1833 |
|
|
|
1834 |
|
✗ |
ret = gate_microservice_get_parameter_names(ptr_svc, ¶m_names); |
1835 |
|
✗ |
if (GATE_SUCCEEDED(ret)) |
1836 |
|
|
{ |
1837 |
|
✗ |
if (NULL != gate_property_create_object(&service_params)) |
1838 |
|
|
{ |
1839 |
|
✗ |
name_count = gate_array_length(¶m_names); |
1840 |
|
✗ |
for (name_index = 0; name_index != name_count; ++name_index) |
1841 |
|
|
{ |
1842 |
|
✗ |
ptr_param_name = (gate_string_t const*)gate_array_get(¶m_names, name_index); |
1843 |
|
✗ |
if (ptr_param_name) |
1844 |
|
|
{ |
1845 |
|
✗ |
ret = gate_microservice_get_parameter(ptr_svc, ptr_param_name, &prop); |
1846 |
|
✗ |
if (GATE_FAILED(ret)) |
1847 |
|
|
{ |
1848 |
|
✗ |
continue; |
1849 |
|
|
} |
1850 |
|
✗ |
gate_property_member_add(&service_params, ptr_param_name, &prop); |
1851 |
|
✗ |
gate_property_destroy(&prop); |
1852 |
|
|
} |
1853 |
|
|
} |
1854 |
|
✗ |
gate_mem_copy(&cfg_svc.parameters, &service_params, sizeof(gate_property_t)); |
1855 |
|
|
} |
1856 |
|
✗ |
gate_array_release(¶m_names); |
1857 |
|
|
} |
1858 |
|
✗ |
gate_arraylist_add(config->services, &cfg_svc.struct_base); |
1859 |
|
✗ |
gate_struct_release(&cfg_svc.struct_base); |
1860 |
|
|
} |
1861 |
|
|
} |
1862 |
|
|
|
1863 |
|
|
} while (0); |
1864 |
|
|
|
1865 |
|
✗ |
if (ptr_svc != NULL) |
1866 |
|
|
{ |
1867 |
|
✗ |
gate_object_release(ptr_svc); |
1868 |
|
✗ |
ptr_svc = NULL; |
1869 |
|
|
} |
1870 |
|
|
|
1871 |
|
✗ |
gate_array_release(&addresses); |
1872 |
|
✗ |
return ret; |
1873 |
|
|
} |
1874 |
|
|
|
1875 |
|
✗ |
gate_result_t gate_servicehost_release_services(gate_servicehost_t* host) |
1876 |
|
|
{ |
1877 |
|
|
gate_result_t result; |
1878 |
|
✗ |
gate_array_t addrs = GATE_INIT_EMPTY; |
1879 |
|
|
gate_enumerator_t addrs_enum; |
1880 |
|
|
gate_string_t const* ptr_addr; |
1881 |
|
|
|
1882 |
|
|
do |
1883 |
|
|
{ |
1884 |
|
✗ |
result = gate_servicehost_get_service_addresses(host, &addrs); |
1885 |
|
✗ |
GATE_BREAK_IF_FAILED(result); |
1886 |
|
|
|
1887 |
|
✗ |
if (NULL == gate_array_enumerate(&addrs, &addrs_enum)) |
1888 |
|
|
{ |
1889 |
|
✗ |
result = GATE_RESULT_OUTOFMEMORY; |
1890 |
|
✗ |
break; |
1891 |
|
|
} |
1892 |
|
|
|
1893 |
|
✗ |
GATE_FOR_ENUMERATOR(gate_string_t, ptr_addr, &addrs_enum) |
1894 |
|
|
{ |
1895 |
|
✗ |
gate_servicehost_release_service(host, ptr_addr); |
1896 |
|
|
} |
1897 |
|
|
|
1898 |
|
|
} while (0); |
1899 |
|
|
|
1900 |
|
✗ |
gate_array_release(&addrs); |
1901 |
|
|
|
1902 |
|
✗ |
return result; |
1903 |
|
|
} |
1904 |
|
|
|