GCC Code Coverage Report


Directory: src/gate/
File: src/gate/tech/cxx_microservices.cpp
Date: 2026-03-20 22:56:14
Exec Total Coverage
Lines: 226 438 51.6%
Functions: 54 96 56.2%
Branches: 113 500 22.6%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2026, 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/microservices.hpp"
30
31 namespace gate
32 {
33 namespace tech
34 {
35
36 /******************************
37 * MicroHost implementation *
38 ******************************/
39
40 1 MicroHost::MicroHost(gate_microhost_t* host) noexcept
41 1 : object_impl_t(host)
42 {
43 1 }
44
45 1 MicroHost::~MicroHost() noexcept
46 {
47
48 1 }
49
50 void MicroHost::publishMessage(String const& sourceAddress, String const& destinationAddress, String const& msgId, String const& message)
51 {
52 result_t result = gate_microhost_publish_message(this->c_impl(),
53 sourceAddress.c_impl(), destinationAddress.c_impl(),
54 msgId.c_impl(), message.c_impl());
55 GATEXX_CHECK_EXCEPTION(result);
56 }
57 void MicroHost::publishObject(String const& sourceAddress, String const& destinationAddress, String const& objId, Object& obj)
58 {
59 result_t result = gate_microhost_publish_object(this->c_impl(),
60 sourceAddress.c_impl(), destinationAddress.c_impl(),
61 objId.c_impl(), obj.c_impl());
62 GATEXX_CHECK_EXCEPTION(result);
63 }
64
65 void MicroHost::subscribeMessages(String const& sourceAddress, String const& destinationAddress, String const& msgId, MicroService& obj, void* userData)
66 {
67 result_t result = gate_microhost_subscribe_messages(this->c_impl(),
68 sourceAddress.c_impl(), destinationAddress.c_impl(),
69 msgId.c_impl(), obj.c_impl(), userData);
70 GATEXX_CHECK_EXCEPTION(result);
71 }
72 void MicroHost::unsubscribeMessages(String const& sourceAddress, String const& destinationAddress, String const& msgId, MicroService& obj, void* userData)
73 {
74 result_t result = gate_microhost_unsubscribe_messages(this->c_impl(),
75 sourceAddress.c_impl(), destinationAddress.c_impl(),
76 msgId.c_impl(), obj.c_impl(), userData);
77 GATEXX_CHECK_EXCEPTION(result);
78 }
79
80 void MicroHost::subscribeObjects(String const& sourceAddress, String const& destinationAddress, String const& objId, MicroService& obj, void* userData)
81 {
82 result_t result = gate_microhost_subscribe_objects(this->c_impl(),
83 sourceAddress.c_impl(), destinationAddress.c_impl(),
84 objId.c_impl(), obj.c_impl(), userData);
85 GATEXX_CHECK_EXCEPTION(result);
86 }
87 void MicroHost::unsubscribeObjects(String const& sourceAddress, String const& destinationAddress, String const& objId, MicroService& obj, void* userData)
88 {
89 result_t result = gate_microhost_unsubscribe_objects(this->c_impl(),
90 sourceAddress.c_impl(), destinationAddress.c_impl(),
91 objId.c_impl(), obj.c_impl(), userData);
92 GATEXX_CHECK_EXCEPTION(result);
93 }
94
95 void MicroHost::remoteInvoke(String const& destinationAddress, String const& method, ConstStruct& inputData, MutableStruct& outputData)
96 {
97 result_t result = gate_microhost_remote_invoke(this->c_impl(),
98 destinationAddress.c_impl(), method.c_impl(),
99 inputData.c_impl(), outputData.c_impl());
100 GATEXX_CHECK_EXCEPTION(result);
101 }
102
103 void MicroHost::log(uint32_t logType, result_t resultCode, int32_t nativeCode, String const& origin, String const& message)
104 {
105 result_t result = gate_microhost_log(this->c_impl(),
106 logType, resultCode, nativeCode,
107 origin.c_impl(), message.c_impl());
108 GATEXX_CHECK_EXCEPTION(result);
109 }
110
111
112
113
114 /*********************************
115 * MicroService implementation *
116 *********************************/
117
118 2 MicroService::MicroService(gate_microservice_t* service) noexcept
119 2 : Startable((gate_startable_t*)service)
120 {
121 2 }
122
123 35 gate_microservice_t* MicroService::c_impl() const noexcept
124 {
125 35 return reinterpret_cast<gate_microservice_t*>(Startable::c_impl());
126 }
127
128
129 void MicroService::setup(String const& instanceAddress, MicroHost& host)
130 {
131 result_t result = gate_microservice_setup(this->c_impl(), instanceAddress.c_impl(), host.c_impl());
132 GATEXX_CHECK_EXCEPTION(result);
133 }
134 String MicroService::getAddress()
135 {
136 gate_string_t tmp;
137 result_t result = gate_microservice_get_address(this->c_impl(), &tmp);
138 GATEXX_CHECK_ERROR(result);
139 return String::createFrom(tmp);
140 }
141 1 enumint_t MicroService::getConditionBits()
142 {
143 1 enumint_t condition = 0;
144
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 result_t result = gate_microservice_get_condition_bits(this->c_impl(), &condition);
145
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_ERROR(result);
146 1 return condition;
147 }
148
149 1 Array<String> MicroService::getParameterNames()
150 {
151 1 Array<String> ret;
152 gate_array_t tmp;
153
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 result_t result = gate_microservice_get_parameter_names(this->c_impl(), &tmp);
154
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_ERROR(result);
155
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 return util::createStringArray(tmp).toArray();
156 }
157 4 Property::TypeEnum MicroService::getParameterType(String const& paramName)
158 {
159 4 uint32_t type = 0;
160
1/2
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 result_t result = gate_microservice_get_parameter_type(this->c_impl(), paramName.c_impl(), &type);
161
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 GATEXX_CHECK_EXCEPTION(result);
162 4 return (Property::TypeEnum)type;
163 }
164 4 Property MicroService::getParameter(String const& paramName)
165 {
166 gate_property_t tmp;
167
1/2
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 result_t result = gate_microservice_get_parameter(this->c_impl(), paramName.c_impl(), &tmp);
168
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 GATEXX_CHECK_EXCEPTION(result);
169
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 return Property::createFrom(tmp);
170 }
171 7 void MicroService::setParameter(String const& paramName, Property const& value)
172 {
173 7 result_t result = gate_microservice_set_parameter(this->c_impl(), paramName.c_impl(), value.c_impl());
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 GATEXX_CHECK_EXCEPTION(result);
175 7 }
176
177
178
179
180 2 MicroServiceActivities::~MicroServiceActivities() noexcept
181 {
182 2 }
183
184 /*************************************
185 * MicroServiceBase implementation *
186 *************************************/
187
188
189 1 MicroServiceBase::MicroServiceBase(String const& serviceName)
190 : impl(),
191 name(serviceName),
192 status(MicroService::Status_Offline),
193 conditionBits(0),
194 host(NULL),
195
2/4
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 genericParameters(Property::object_members_t())
196 {
197 static GATE_INTERFACE_VTBL(gate_microservice) local_vtbl = {
198 &MicroServiceBase::msi_get_interface_name,
199 &MicroServiceBase::msi_release,
200 &MicroServiceBase::msi_retain,
201 &MicroServiceBase::msi_start,
202 &MicroServiceBase::msi_stop,
203 &MicroServiceBase::msi_get_status,
204 &MicroServiceBase::msi_setup,
205 &MicroServiceBase::msi_get_address,
206 &MicroServiceBase::msi_get_condition_bits,
207 &MicroServiceBase::msi_process_message,
208 &MicroServiceBase::msi_process_object,
209 &MicroServiceBase::msi_invoke,
210 &MicroServiceBase::msi_get_parameter_names,
211 &MicroServiceBase::msi_get_parameter_type,
212 &MicroServiceBase::msi_get_parameter,
213 &MicroServiceBase::msi_set_parameter
214 };
215
216 1 this->impl.vtbl = &local_vtbl;
217
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 gate_atomic_int_init(&this->impl.refcounter, 0);
218 1 this->impl.parent = this;
219 1 }
220
221 2 MicroServiceBase::~MicroServiceBase() noexcept
222 {
223 2 GATEXX_TRY_IGNORE({
224 this->onDestroy();
225 });
226 2 }
227
228 1 MicroService MicroServiceBase::getInstance()
229 {
230 1 MicroService service(&this->impl);
231
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 gate_object_retain(&this->impl);
232 1 return service;
233 }
234
235
236 1 MicroServiceBase::StatusEnum MicroServiceBase::getStatus()
237 {
238 1 return this->onReadStatus();
239 }
240 1 enumint_t MicroServiceBase::getConditionBits()
241 {
242 1 return this->onReadConditionBits();
243 }
244 void MicroServiceBase::setup(String const& instanceAddress, MicroHost& hostInterface)
245 {
246 if (!this->updateStatus(MicroService::Status_Offline, MicroService::Status_Configure))
247 {
248 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in offline state", 0);
249 }
250
251 this->address = instanceAddress;
252 this->host = hostInterface;
253 this->updateStatus(MicroService::Status_Offline);
254 }
255
256 void MicroServiceBase::start()
257 {
258 if (!this->updateStatus(MicroService::Status_Offline, MicroService::Status_Starting))
259 {
260 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in offline state", 0);
261 }
262
263 GATEXX_TRY_CATCHALL({
264 this->onStart();
265 }, {
266 this->updateStatus(MicroService::Status_Offline);
267 throw;
268 });
269
270 this->updateStatus(MicroService::Status_Online);
271 }
272
273 void MicroServiceBase::stop()
274 {
275 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Stopping))
276 {
277 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in line state", 0);
278 }
279 GATEXX_TRY_CATCHALL(
280 {
281 this->onStop();
282 },
283 {
284 // exception:
285 //this->updateStatus(MicroService::Status_Online);
286 this->updateStatus(MicroService::Status_Error);
287 throw;
288 }
289 );
290 this->updateStatus(MicroService::Status_Offline);
291 }
292
293 template<class KEY, class VALUE, class COMP>
294 8 void addMapKeysToArrayList(Map<KEY, VALUE, COMP> const& mapping, ArrayList<KEY>& keys)
295 {
296 8 Enumerator<KEY const> e = mapping.enumerateKeys();
297
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
16 for(; e.valid(); e.next())
298 {
299
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 keys.add(*e);
300 }
301 8 }
302
303 template<class KEY, class VALUE, class COMP>
304 60 VALUE getMappedValue(Map<KEY, VALUE, COMP> const& mapping, KEY const& key)
305 {
306 typedef typename Map<KEY, VALUE, COMP>::const_iterator iter_t;
307 120 iter_t const iter = mapping.get(key);
308
2/2
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 12 times.
60 if(iter == mapping.end())
309 {
310 36 return NULL;
311 }
312 else
313 {
314 24 return iter.value();
315 }
316 }
317
318 1 Array<String> MicroServiceBase::getParameterNames()
319 {
320 1 StringArray names;
321
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 this->onListParameterNames(names);
322 1 return names;
323 }
324 4 Property::TypeEnum MicroServiceBase::getParameterType(String const& paramName)
325 {
326 4 Property::TypeEnum propType = Property::Type_Empty;
327
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 this->onReadParameterType(paramName, propType);
328 4 return propType;
329 }
330 4 Property MicroServiceBase::getParameter(String const& paramName)
331 {
332 4 Property prop;
333
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 this->onReadParameterValue(paramName, prop);
334 4 return prop;
335 }
336 4 void MicroServiceBase::setParameter(String const& paramName, Property const& value)
337 {
338 4 this->onWriteParameterValue(paramName, value);
339 4 }
340
341 1 MicroServiceBase::StatusEnum MicroServiceBase::onReadStatus()
342 {
343 1 return static_cast<MicroServiceBase::StatusEnum>(this->status.get());
344 }
345 1 enumint_t MicroServiceBase::onReadConditionBits()
346 {
347 1 return static_cast<enumint_t>(this->conditionBits.get());
348 }
349
350 void MicroServiceBase::onStart()
351 {
352 // override by derived class
353 }
354 void MicroServiceBase::onStop()
355 {
356 // override by derived class
357 }
358 2 void MicroServiceBase::onDestroy()
359 {
360 // override by derived class
361 2 }
362 void MicroServiceBase::onMessageReceived(String const& source, String const& destination, String const& msgId, String const& message)
363 {
364 GATE_UNUSED_ARG(source);
365 GATE_UNUSED_ARG(destination);
366 GATE_UNUSED_ARG(msgId);
367 GATE_UNUSED_ARG(message);
368 // override by derived class
369 }
370 void MicroServiceBase::onObjectReceived(String const& source, String const& destination, String const& objId, Object& obj)
371 {
372 GATE_UNUSED_ARG(source);
373 GATE_UNUSED_ARG(destination);
374 GATE_UNUSED_ARG(objId);
375 GATE_UNUSED_ARG(obj);
376 // override by derived class
377 }
378 void MicroServiceBase::onInvoke(String const& method, ConstStruct const& request, MutableStruct& response)
379 {
380 GATE_UNUSED_ARG(method);
381 GATE_UNUSED_ARG(request);
382 GATE_UNUSED_ARG(response);
383 // override by derived class
384 }
385
386 1 void MicroServiceBase::registerParameter(String const& name, bool_t& value)
387 {
388
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 this->boolParameters.add(name, &value);
389 1 }
390 1 void MicroServiceBase::registerParameter(String const& name, int64_t& value)
391 {
392
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 this->intParameters.add(name, &value);
393 1 }
394 1 void MicroServiceBase::registerParameter(String const& name, real64_t& value)
395 {
396
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 this->realParameters.add(name, &value);
397 1 }
398 1 void MicroServiceBase::registerParameter(String const& name, String& value)
399 {
400
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 this->stringParameters.add(name, &value);
401 1 }
402
403
404 1 void MicroServiceBase::onListParameterNames(Array<String>& names)
405 {
406
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 ArrayList<String> keys;
407
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addMapKeysToArrayList(this->boolParameters, keys);
408
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addMapKeysToArrayList(this->intParameters, keys);
409
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addMapKeysToArrayList(this->realParameters, keys);
410
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addMapKeysToArrayList(this->stringParameters, keys);
411
412
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Array<String> const genericKeys = this->genericParameters.getObjectMemberNames();
413
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 keys.addItems(genericKeys.begin(), genericKeys.end());
414
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 names = keys.toArray();
415 1 }
416 4 void MicroServiceBase::onReadParameterType(String const& paramName, TypeEnum& type)
417 {
418
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 if(NULL != getMappedValue(this->boolParameters, paramName))
419 {
420 1 type = Property::Type_Bool;
421 }
422
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 else if(NULL != getMappedValue(this->intParameters, paramName))
423 {
424 1 type = Property::Type_Int;
425 }
426
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 else if(NULL != getMappedValue(this->realParameters, paramName))
427 {
428 1 type = Property::Type_Real;
429 }
430
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 else if(NULL != getMappedValue(this->stringParameters, paramName))
431 {
432 1 type = Property::Type_String;
433 }
434 else
435 {
436 Property prop = this->genericParameters.getObjectMember(paramName);
437 type = prop.getType();
438 }
439 4 }
440 4 void MicroServiceBase::onReadParameterValue(String const& paramName, Property& value)
441 {
442 4 bool_t* const ptrBool = getMappedValue(this->boolParameters, paramName);
443
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (ptrBool)
444 {
445
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 value = Property(*ptrBool);
446 1 return;
447 }
448
449 3 int64_t* const ptrInt = getMappedValue(this->intParameters, paramName);
450
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (ptrInt)
451 {
452
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 value = Property(*ptrInt);
453 1 return;
454 }
455
456 2 real64_t* const ptrReal = getMappedValue(this->realParameters, paramName);
457
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (ptrReal)
458 {
459
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 value = Property(*ptrReal);
460 1 return;
461 }
462
463 1 String* const ptrStr = getMappedValue(this->stringParameters, paramName);
464
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptrStr)
465 {
466
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 value = Property(*ptrStr);
467 1 return;
468 }
469
470 value = this->genericParameters.getObjectMember(paramName);
471 }
472 4 void MicroServiceBase::onWriteParameterValue(String const& paramName, Property const& value)
473 {
474 4 bool_t* const ptrBool = getMappedValue(this->boolParameters, paramName);
475
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (ptrBool)
476 {
477 1 *ptrBool = value.getBool();
478 1 return;
479 }
480
481 3 int64_t* const ptrInt = getMappedValue(this->intParameters, paramName);
482
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (ptrInt)
483 {
484 1 *ptrInt = value.getInt();
485 1 return;
486 }
487
488 2 real64_t* const ptrReal = getMappedValue(this->realParameters, paramName);
489
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (ptrReal)
490 {
491 1 *ptrReal = value.getReal();
492 1 return;
493 }
494
495 1 String* const ptrStr = getMappedValue(this->stringParameters, paramName);
496
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptrStr)
497 {
498 1 *ptrStr = value.getString();
499 1 return;
500 }
501
502 this->genericParameters.addObjectMember(paramName, value);
503 }
504
505
506 String MicroServiceBase::getAddress() const
507 {
508 return this->address;
509 }
510 void MicroServiceBase::publishMessage(String const& destinationAddress, String const& msgId, String const& message)
511 {
512 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
513 {
514 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
515 }
516 this->host.publishMessage(this->getAddress(), destinationAddress, msgId, message);
517 }
518 void MicroServiceBase::publishObject(String const& destinationAddress, String const& objId, Object& obj)
519 {
520 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
521 {
522 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
523 }
524 this->host.publishObject(this->getAddress(), destinationAddress, objId, obj);
525 }
526 void MicroServiceBase::subscribeMessages(String const& sourceAddress, String const& destAddress, String const& msgId)
527 {
528 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
529 {
530 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
531 }
532 MicroService instance = this->getInstance();
533 this->host.subscribeMessages(sourceAddress, destAddress, msgId, instance, this);
534 }
535 void MicroServiceBase::unsubscribeMessages(String const& sourceAddress, String const& destAddress, String const& msgId)
536 {
537 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
538 {
539 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
540 }
541 MicroService instance = this->getInstance();
542 this->host.unsubscribeMessages(sourceAddress, destAddress, msgId, instance, this);
543 }
544 void MicroServiceBase::subscribeObjects(String const& sourceAddress, String const& destAddress, String const& objId)
545 {
546 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
547 {
548 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
549 }
550 MicroService instance = this->getInstance();
551 this->host.subscribeMessages(sourceAddress, destAddress, objId, instance, this);
552 }
553 void MicroServiceBase::unsubscribeObjects(String const& sourceAddress, String const& destAddress, String const& objId)
554 {
555 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
556 {
557 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
558 }
559 MicroService instance = this->getInstance();
560 this->host.unsubscribeMessages(sourceAddress, destAddress, objId, instance, this);
561 }
562 void MicroServiceBase::log(LogTypeEnum type, result_t resultCode, String const& message, int32_t nativeCode)
563 {
564 if (!this->host.empty())
565 {
566 this->host.log(type, resultCode, nativeCode, this->address, message);
567 }
568 }
569 void MicroServiceBase::updateStatus(MicroService::StatusEnum newStatus)
570 {
571 this->status.set(static_cast<int32_t>(newStatus));
572 }
573 bool_t MicroServiceBase::updateStatus(MicroService::StatusEnum fromStatus, MicroService::StatusEnum toStatus)
574 {
575 MicroService::StatusEnum oldStatus = static_cast<MicroService::StatusEnum>(
576 this->status.changeIf(static_cast<int32_t>(fromStatus), static_cast<int32_t>(toStatus)));
577 return (oldStatus == fromStatus);
578 }
579 bool_t MicroServiceBase::setConditionBits(uint32_t bits)
580 {
581 int32_t addBits = static_cast<int32_t>(bits);
582 int32_t oldBits, newBits;
583 do
584 {
585 oldBits = this->conditionBits.get();
586 newBits = oldBits | addBits;
587 } while (oldBits != this->conditionBits.changeIf(oldBits, newBits));
588 return true;
589 }
590 bool_t MicroServiceBase::clearConditionBits(uint32_t bits)
591 {
592 int32_t delBits = static_cast<int32_t>(bits);
593 int32_t oldBits, newBits;
594 do
595 {
596 oldBits = this->conditionBits.get();
597 newBits = oldBits & (~delBits);
598 } while (oldBits != this->conditionBits.changeIf(oldBits, newBits));
599 return true;
600 }
601
602
603 1 char const* MicroServiceBase::msi_get_interface_name(void* thisptr)
604 {
605 1 return GATE_INTERFACE_NAME_MICROSERVICE;
606 }
607 1 void MicroServiceBase::msi_release(void* thisptr)
608 {
609 1 microservice_impl* self = (microservice_impl*)thisptr;
610
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (gate_atomic_int_dec(&self->refcounter) == 0)
611 {
612 1 MicroServiceBase* ms = self->parent;
613 1 self->parent = NULL;
614
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ms)
615 {
616
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 GATEXX_TRY_IGNORE({
617 ms->onDestroy();
618 });
619
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 delete ms;
620 }
621 }
622 1 }
623 1 int MicroServiceBase::msi_retain(void* thisptr)
624 {
625 1 microservice_impl* self = (microservice_impl*)thisptr;
626 1 return gate_atomic_int_inc(&self->refcounter);
627 }
628
629 #define MICROSERVICEBASE_CALL(thisptr, func_call) \
630 microservice_impl* self = (microservice_impl*)thisptr; \
631 if(!self->parent) return GATE_RESULT_INVALIDSTATE; \
632 ExceptionInfo xcptInfo; \
633 GATEXX_TRY_CATCHINFO(xcptInfo, { \
634 self->parent-> func_call ; \
635 }); \
636 if (xcptInfo.failed()) { \
637 return xcptInfo.result_code; \
638 }
639
640 #define MICROSERVICEBASE_CALL_RET(thisptr, ret_var, func_call) \
641 microservice_impl* self = (microservice_impl*)thisptr; \
642 if(!self->parent) return GATE_RESULT_INVALIDSTATE; \
643 ExceptionInfo xcptInfo; \
644 GATEXX_TRY_CATCHINFO(xcptInfo, { \
645 ret_var = self->parent-> func_call ; \
646 }); \
647 if (xcptInfo.failed()) { \
648 return xcptInfo.result_code; \
649 }
650
651
652 gate_result_t MicroServiceBase::msi_start(void* thisptr)
653 {
654 MICROSERVICEBASE_CALL(thisptr, onStart());
655 return GATE_RESULT_OK;
656 }
657 gate_result_t MicroServiceBase::msi_stop(void* thisptr)
658 {
659 MICROSERVICEBASE_CALL(thisptr, onStop());
660 return GATE_RESULT_OK;
661 }
662 1 gate_enumint_t MicroServiceBase::msi_get_status(void* thisptr)
663 {
664 1 microservice_impl* self = (microservice_impl*)thisptr;
665
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!self->parent) return GATE_RESULT_INVALIDSTATE;
666 1 return (gate_enumint_t)self->parent->getStatus();
667 }
668
669 gate_result_t MicroServiceBase::msi_setup(void* thisptr, gate_string_t const* instance_address, gate_microhost_t* host)
670 {
671 String address(*instance_address);
672 MicroHost microhost(host);
673 gate_object_retain(host);
674
675 MICROSERVICEBASE_CALL(thisptr, setup(address, microhost));
676 return GATE_RESULT_OK;
677 }
678 gate_result_t MicroServiceBase::msi_get_address(void* thisptr, gate_string_t* ptr_output_address)
679 {
680 String address;
681 MICROSERVICEBASE_CALL_RET(thisptr, address, getAddress());
682 if (ptr_output_address)
683 {
684 gate_string_clone(ptr_output_address, address.c_impl());
685 }
686 return GATE_RESULT_OK;
687 }
688 1 gate_result_t MicroServiceBase::msi_get_condition_bits(void* thisptr, gate_enumint_t* ptr_bits)
689 {
690 1 enumint_t stat = 0;
691
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 MICROSERVICEBASE_CALL_RET(thisptr, stat, getConditionBits());
692
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr_bits)
693 {
694 1 *ptr_bits = stat;
695 }
696 1 return GATE_RESULT_OK;
697 }
698
699 gate_result_t MicroServiceBase::msi_process_message(void* thisptr,
700 gate_string_t const* source_service_address, gate_string_t const* publish_channel,
701 gate_string_t const* msg_id, gate_string_t const* message, void* user_param)
702 {
703 String source(*source_service_address);
704 String channel(*publish_channel);
705 String id(*msg_id);
706 String msg(*message);
707
708 MICROSERVICEBASE_CALL(thisptr, onMessageReceived(source, channel, id, msg));
709 return GATE_RESULT_OK;
710 }
711
712 gate_result_t MicroServiceBase::msi_process_object(void* thisptr,
713 gate_string_t const* source_service_address, gate_string_t const* publish_channel,
714 gate_string_t const* obj_id, gate_object_t* ptr_object, void* user_param)
715 {
716 String source(*source_service_address);
717 String channel(*publish_channel);
718 String id(*obj_id);
719 Object obj(ptr_object);
720 gate_object_retain(ptr_object);
721
722 MICROSERVICEBASE_CALL(thisptr, onObjectReceived(source, channel, id, obj));
723 return GATE_RESULT_OK;
724 }
725
726 gate_result_t MicroServiceBase::msi_invoke(void* thisptr,
727 gate_string_t const* method, gate_struct_t const* request, gate_struct_t* response)
728 {
729 String methodName(*method);
730 ConstStruct requestStruct(request);
731 MutableStruct responseStruct(response);
732
733 MICROSERVICEBASE_CALL(thisptr, onInvoke(methodName, requestStruct, responseStruct));
734 return GATE_RESULT_OK;
735 }
736
737 1 gate_result_t MicroServiceBase::msi_get_parameter_names(void* thisptr, gate_array_t* ptr_output_names)
738 {
739 2 StringArray names;
740
741
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 MICROSERVICEBASE_CALL_RET(thisptr, names, getParameterNames());
742
743
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr_output_names)
744 {
745
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 gate_array_duplicate(ptr_output_names, names.c_impl());
746 }
747 1 return GATE_RESULT_OK;
748 }
749
750 4 gate_result_t MicroServiceBase::msi_get_parameter_type(void* thisptr, gate_string_t const* name, gate_uint32_t* ptr_output_type)
751 {
752
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 String const paramName(*name);
753 4 Property::TypeEnum paramType = Property::Type_Empty;
754
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
4 MICROSERVICEBASE_CALL_RET(thisptr, paramType, getParameterType(paramName));
755
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ptr_output_type)
756 {
757 4 *ptr_output_type = (gate_enumint_t)paramType;
758 }
759
760 4 return GATE_RESULT_OK;
761 }
762
763 4 gate_result_t MicroServiceBase::msi_get_parameter(void* thisptr, gate_string_t const* name, gate_property_t* ptr_output_value)
764 {
765
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 String const paramName(*name);
766
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 Property prop;
767
6/16
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 4 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
4 MICROSERVICEBASE_CALL_RET(thisptr, prop, getParameter(paramName));
768
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ptr_output_value)
769 {
770
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
4 if (NULL == gate_property_copy(ptr_output_value, prop.c_impl()))
771 {
772 return GATE_RESULT_OUTOFMEMORY;
773 }
774 }
775 4 return GATE_RESULT_OK;
776 }
777
778 4 gate_result_t MicroServiceBase::msi_set_parameter(void* thisptr, gate_string_t const* name, gate_property_t const* value)
779 {
780
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 String const paramName(*name);
781
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 Property prop;
782
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (value != NULL)
783 {
784
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 prop = Property(*value);
785 }
786
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
4 MICROSERVICEBASE_CALL(thisptr, setParameter(paramName, prop));
787 4 return GATE_RESULT_OK;
788 }
789
790
791 /*********************************
792 * MicroFactory implementation *
793 *********************************/
794
795 2 MicroFactory::MicroFactory(gate_microfactory_t* impl) noexcept
796 2 : object_impl_t(impl)
797 {
798 2 }
799
800 2 MicroFactory::~MicroFactory() noexcept
801 {
802 2 }
803
804 Array<String> MicroFactory::getSupportedServiceNames()
805 {
806 Array<String> ret;
807 gate_array_t names = GATE_INIT_EMPTY;
808 result_t result = gate_microfactory_supported_service_names(this->c_impl(), &names);
809 GATEXX_CHECK_ERROR(result);
810 return util::createStringArray(names).toArray();
811 }
812
813 MicroService MicroFactory::createService(String const& serviceName)
814 {
815 gate_microservice_t* ptr_service = NULL;
816 result_t result = gate_microfactory_create_service(this->c_impl(), serviceName.c_impl(), &ptr_service);
817 GATEXX_CHECK_EXCEPTION(result);
818 return MicroService(ptr_service);
819 }
820
821
822
823
824 /*************************************
825 * MicroFactoryBase implementation *
826 *************************************/
827
828 1 MicroFactoryBase::MicroFactoryBase()
829 {
830 static GATE_INTERFACE_VTBL(gate_microfactory) local_vtbl = {
831 &MicroFactoryBase::mf_get_interface_name,
832 &MicroFactoryBase::mf_release,
833 &MicroFactoryBase::mf_retain,
834 &MicroFactoryBase::mf_supported_service_names,
835 &MicroFactoryBase::mf_create_service
836 };
837
838 1 this->impl.vtbl = &local_vtbl;
839 1 gate_atomic_int_init(&this->impl.refcounter, 0);
840 1 this->impl.parent = this;
841 1 }
842 2 MicroFactoryBase::~MicroFactoryBase() noexcept
843 {
844 2 }
845
846 1 MicroFactory MicroFactoryBase::getInstance()
847 {
848 1 MicroFactory factory(&this->impl);
849
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 gate_object_retain(&this->impl);
850 1 return factory;
851 }
852
853 char const* MicroFactoryBase::mf_get_interface_name(void* thisptr)
854 {
855 return GATE_INTERFACE_NAME_MICROFACTORY;
856 }
857 2 void MicroFactoryBase::mf_release(void* thisptr)
858 {
859 2 microfactory_impl* impl = (microfactory_impl*)thisptr;
860
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (gate_atomic_int_dec(&impl->refcounter) == 0)
861 {
862 1 MicroFactoryBase* ptr = impl->parent;
863 1 impl->parent = NULL;
864
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 delete ptr;
865 }
866 2 }
867 2 int MicroFactoryBase::mf_retain(void* thisptr)
868 {
869 2 microfactory_impl* impl = (microfactory_impl*)thisptr;
870 2 return gate_atomic_int_inc(&impl->refcounter);
871 }
872
873 gate_result_t MicroFactoryBase::mf_supported_service_names(void* thisptr, gate_array_t* ptr_output_names)
874 {
875 microfactory_impl* impl = (microfactory_impl*)thisptr;
876 MicroFactoryBase* ptr = impl->parent;
877 if (!ptr)
878 {
879 return GATE_RESULT_INVALIDSTATE;
880 }
881 StringArray names;
882 ExceptionInfo xcptInfo;
883 GATEXX_TRY_CATCHINFO(xcptInfo, {
884 names = ptr->getSupportedServiceNames();
885 });
886 if (xcptInfo.failed())
887 {
888 return xcptInfo.result_code;
889 }
890
891 GenericArrayList namesList(gate::util::convertStringArray(names));
892 if (NULL == namesList.c_impl())
893 {
894 return GATE_RESULT_OUTOFMEMORY;
895 }
896 gate_result_t ret = GATE_RESULT_OK;
897 if (ptr_output_names)
898 {
899 if (NULL == gate_array_create(ptr_output_names, namesList.c_impl()))
900 {
901 ret = GATE_RESULT_OUTOFMEMORY;
902 }
903 }
904 return ret;
905 }
906
907 gate_result_t MicroFactoryBase::mf_create_service(void* thisptr, gate_string_t const* service_name, gate_microservice_t** ptr_service)
908 {
909 microfactory_impl* impl = (microfactory_impl*)thisptr;
910 MicroFactoryBase* ptr = impl->parent;
911 if (!ptr)
912 {
913 return GATE_RESULT_INVALIDSTATE;
914 }
915
916 ExceptionInfo xcptInfo;
917 GATEXX_TRY_CATCHINFO(xcptInfo, {
918 String name(*service_name);
919 MicroService svc = ptr->createService(name);
920
921 if (ptr_service)
922 {
923 *ptr_service = svc.c_impl();
924 gate_object_retain(*ptr_service);
925 }
926 });
927 return xcptInfo.result_code;
928 }
929
930
931 } // end of namespace tech
932 } // end of namespace gate
933