GCC Code Coverage Report


Directory: src/gate/
File: src/gate/tech/cxx_microservices.cpp
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 0 372 0.0%
Functions: 0 88 0.0%
Branches: 0 260 0.0%

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/microservices.hpp"
30
31 namespace gate
32 {
33 namespace tech
34 {
35
36 /******************************
37 * MicroHost implementation *
38 ******************************/
39
40 MicroHost::MicroHost(gate_microhost_t* host) noexcept
41 : object_impl_t(host)
42 {
43 }
44
45 MicroHost::~MicroHost() noexcept
46 {
47
48 }
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 MicroService::MicroService(gate_microservice_t* service) noexcept
119 : Startable((gate_startable_t*)service)
120 {
121 }
122
123 gate_microservice_t* MicroService::c_impl() const noexcept
124 {
125 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 uint32_t MicroService::getConditionBits()
142 {
143 enumint_t condition = 0;
144 result_t result = gate_microservice_get_condition_bits(this->c_impl(), &condition);
145 GATEXX_CHECK_ERROR(result);
146 return condition;
147 }
148
149 Array<String> MicroService::getParameterNames()
150 {
151 Array<String> ret;
152 gate_array_t tmp;
153 result_t result = gate_microservice_get_parameter_names(this->c_impl(), &tmp);
154 GATEXX_CHECK_ERROR(result);
155 return util::createStringArray(tmp).toArray();
156 }
157 Property::TypeEnum MicroService::getParameterType(String const& paramName)
158 {
159 uint32_t type = 0;
160 result_t result = gate_microservice_get_parameter_type(this->c_impl(), paramName.c_impl(), &type);
161 GATEXX_CHECK_EXCEPTION(result);
162 return (Property::TypeEnum)type;
163 }
164 Property MicroService::getParameter(String const& paramName)
165 {
166 gate_property_t tmp;
167 result_t result = gate_microservice_get_parameter(this->c_impl(), paramName.c_impl(), &tmp);
168 GATEXX_CHECK_EXCEPTION(result);
169 return Property::createFrom(tmp);
170 }
171 void MicroService::setParameter(String const& paramName, Property const& value)
172 {
173 result_t result = gate_microservice_set_parameter(this->c_impl(), paramName.c_impl(), value.c_impl());
174 GATEXX_CHECK_EXCEPTION(result);
175 }
176
177
178
179
180 MicroServiceActivities::~MicroServiceActivities() noexcept
181 {
182 }
183
184 /*************************************
185 * MicroServiceBase implementation *
186 *************************************/
187
188
189 MicroServiceBase::MicroServiceBase(String const& serviceName)
190 : impl(),
191 name(serviceName),
192 status(MicroService::Status_Offline),
193 conditionBits(0),
194 host(NULL),
195 parameters(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 this->impl.vtbl = &local_vtbl;
217 gate_atomic_int_init(&this->impl.refcounter, 0);
218 this->impl.parent = this;
219 }
220
221 MicroServiceBase::~MicroServiceBase() noexcept
222 {
223 try
224 {
225 this->onDestroy();
226 }
227 catch (...)
228 {
229 }
230 }
231
232 MicroService MicroServiceBase::getInstance()
233 {
234 MicroService service(&this->impl);
235 gate_object_retain(&this->impl);
236 return service;
237 }
238
239
240 MicroServiceBase::StatusEnum MicroServiceBase::getStatus()
241 {
242 return this->onReadStatus();
243 }
244 enumint_t MicroServiceBase::getConditionBits()
245 {
246 return this->onReadConditionBits();
247 }
248 void MicroServiceBase::setup(String const& instanceAddress, MicroHost& hostInterface)
249 {
250 if (!this->updateStatus(MicroService::Status_Offline, MicroService::Status_Configure))
251 {
252 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in offline state", 0);
253 }
254
255 try
256 {
257 this->address = instanceAddress;
258 this->host = hostInterface;
259 }
260 catch (...)
261 {
262 this->updateStatus(MicroService::Status_Offline);
263 throw;
264 }
265 this->updateStatus(MicroService::Status_Offline);
266 }
267 void MicroServiceBase::start()
268 {
269 if (!this->updateStatus(MicroService::Status_Offline, MicroService::Status_Starting))
270 {
271 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in offline state", 0);
272 }
273
274 try
275 {
276 this->onStart();
277 }
278 catch (...)
279 {
280 this->updateStatus(MicroService::Status_Offline);
281 throw;
282 }
283
284 this->updateStatus(MicroService::Status_Online);
285 }
286
287 void MicroServiceBase::stop()
288 {
289 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Stopping))
290 {
291 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in line state", 0);
292 }
293 try
294 {
295 this->onStop();
296 }
297 catch (...)
298 {
299 //this->updateStatus(MicroService::Status_Online);
300 this->updateStatus(MicroService::Status_Error);
301 }
302 this->updateStatus(MicroService::Status_Offline);
303 }
304
305 Array<String> MicroServiceBase::getParameterNames()
306 {
307 Array<String> ret = this->parameters.getObjectMemberNames();
308 return ret;
309 }
310 Property::TypeEnum MicroServiceBase::getParameterType(String const& paramName)
311 {
312 Property prop = this->parameters.getObjectMember(paramName);
313 return prop.getType();
314 }
315 Property MicroServiceBase::getParameter(String const& paramName)
316 {
317 Property prop = this->parameters.getObjectMember(paramName);
318 return prop;
319 }
320 void MicroServiceBase::setParameter(String const& paramName, Property const& value)
321 {
322 this->parameters.addObjectMember(paramName, value);
323 }
324
325 MicroServiceBase::StatusEnum MicroServiceBase::onReadStatus()
326 {
327 return static_cast<MicroServiceBase::StatusEnum>(this->status.get());
328 }
329 enumint_t MicroServiceBase::onReadConditionBits()
330 {
331 return static_cast<enumint_t>(this->conditionBits.get());
332 }
333
334 void MicroServiceBase::onStart()
335 {
336 // override by derived class
337 }
338 void MicroServiceBase::onStop()
339 {
340 // override by derived class
341 }
342 void MicroServiceBase::onDestroy()
343 {
344
345 }
346 void MicroServiceBase::onMessageReceived(String const& source, String const& destination, String const& msgId, String const& message)
347 {
348 GATE_UNUSED_ARG(source);
349 GATE_UNUSED_ARG(destination);
350 GATE_UNUSED_ARG(msgId);
351 GATE_UNUSED_ARG(message);
352 // override by derived class
353 }
354 void MicroServiceBase::onObjectReceived(String const& source, String const& destination, String const& objId, Object& obj)
355 {
356 GATE_UNUSED_ARG(source);
357 GATE_UNUSED_ARG(destination);
358 GATE_UNUSED_ARG(objId);
359 GATE_UNUSED_ARG(obj);
360 // override by derived class
361 }
362 void MicroServiceBase::onInvoke(String const& method, ConstStruct const& request, MutableStruct& response)
363 {
364 GATE_UNUSED_ARG(method);
365 GATE_UNUSED_ARG(request);
366 GATE_UNUSED_ARG(response);
367 }
368
369 void MicroServiceBase::registerParameter(String const& name, bool_t& value)
370 {
371
372 }
373 void MicroServiceBase::registerParameter(String const& name, int64_t& value)
374 {
375
376 }
377 void MicroServiceBase::registerParameter(String const& name, real64_t& value)
378 {
379
380 }
381 void MicroServiceBase::registerParameter(String const& name, String& value)
382 {
383
384 }
385
386
387 void MicroServiceBase::onListParameterNames(Array<String>& names)
388 {
389 GATE_UNUSED_ARG(names);
390 }
391 void MicroServiceBase::onReadParameterType(String const& paramName, TypeEnum& type)
392 {
393 GATE_UNUSED_ARG(paramName);
394 GATE_UNUSED_ARG(type);
395 }
396 void MicroServiceBase::onReadParameterValue(String const& paramName, Property& value)
397 {
398 GATE_UNUSED_ARG(paramName);
399 GATE_UNUSED_ARG(value);
400 }
401 void MicroServiceBase::onWriteParameterValue(String const& paramName, Property const& value)
402 {
403 GATE_UNUSED_ARG(paramName);
404 GATE_UNUSED_ARG(value);
405 }
406
407
408 String MicroServiceBase::getAddress() const
409 {
410 return this->address;
411 }
412 void MicroServiceBase::publishMessage(String const& destinationAddress, String const& msgId, String const& message)
413 {
414 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
415 {
416 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
417 }
418 this->host.publishMessage(this->getAddress(), destinationAddress, msgId, message);
419 }
420 void MicroServiceBase::publishObject(String const& destinationAddress, String const& objId, Object& obj)
421 {
422 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
423 {
424 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
425 }
426 this->host.publishObject(this->getAddress(), destinationAddress, objId, obj);
427 }
428 void MicroServiceBase::subscribeMessages(String const& sourceAddress, String const& destAddress, String const& msgId)
429 {
430 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
431 {
432 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
433 }
434 MicroService instance = this->getInstance();
435 this->host.subscribeMessages(sourceAddress, destAddress, msgId, instance, this);
436 }
437 void MicroServiceBase::unsubscribeMessages(String const& sourceAddress, String const& destAddress, String const& msgId)
438 {
439 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
440 {
441 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
442 }
443 MicroService instance = this->getInstance();
444 this->host.unsubscribeMessages(sourceAddress, destAddress, msgId, instance, this);
445 }
446 void MicroServiceBase::subscribeObjects(String const& sourceAddress, String const& destAddress, String const& objId)
447 {
448 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
449 {
450 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
451 }
452 MicroService instance = this->getInstance();
453 this->host.subscribeMessages(sourceAddress, destAddress, objId, instance, this);
454 }
455 void MicroServiceBase::unsubscribeObjects(String const& sourceAddress, String const& destAddress, String const& objId)
456 {
457 if (!this->updateStatus(MicroService::Status_Online, MicroService::Status_Online))
458 {
459 GATEXX_RAISE_EXCEPTION(results::InvalidState, "Service not in online state", 0);
460 }
461 MicroService instance = this->getInstance();
462 this->host.unsubscribeMessages(sourceAddress, destAddress, objId, instance, this);
463 }
464 void MicroServiceBase::log(LogTypeEnum type, result_t resultCode, String const& message, int32_t nativeCode)
465 {
466 if (!this->host.empty())
467 {
468 this->host.log(type, resultCode, nativeCode, this->address, message);
469 }
470 }
471 void MicroServiceBase::updateStatus(MicroService::StatusEnum newStatus)
472 {
473 this->status.set(static_cast<int32_t>(newStatus));
474 }
475 bool_t MicroServiceBase::updateStatus(MicroService::StatusEnum fromStatus, MicroService::StatusEnum toStatus)
476 {
477 MicroService::StatusEnum oldStatus = static_cast<MicroService::StatusEnum>(
478 this->status.changeIf(static_cast<int32_t>(fromStatus), static_cast<int32_t>(toStatus)));
479 return (oldStatus == fromStatus);
480 }
481 bool_t MicroServiceBase::setConditionBits(uint32_t bits)
482 {
483 int32_t addBits = static_cast<int32_t>(bits);
484 int32_t oldBits, newBits;
485 do
486 {
487 oldBits = this->conditionBits.get();
488 newBits = oldBits | addBits;
489 } while (oldBits != this->conditionBits.changeIf(oldBits, newBits));
490 return true;
491 }
492 bool_t MicroServiceBase::clearConditionBits(uint32_t bits)
493 {
494 int32_t delBits = static_cast<int32_t>(bits);
495 int32_t oldBits, newBits;
496 do
497 {
498 oldBits = this->conditionBits.get();
499 newBits = oldBits & (~delBits);
500 } while (oldBits != this->conditionBits.changeIf(oldBits, newBits));
501 return true;
502 }
503
504
505 char const* MicroServiceBase::msi_get_interface_name(void* thisptr)
506 {
507 return GATE_INTERFACE_NAME_MICROSERVICE;
508 }
509 void MicroServiceBase::msi_release(void* thisptr)
510 {
511 microservice_impl* self = (microservice_impl*)thisptr;
512 if (gate_atomic_int_dec(&self->refcounter) == 0)
513 {
514 MicroServiceBase* ms = self->parent;
515 self->parent = NULL;
516 if (ms)
517 {
518 try
519 {
520 ms->onDestroy();
521 }
522 catch (...)
523 {
524 }
525 delete ms;
526 }
527 }
528 }
529 int MicroServiceBase::msi_retain(void* thisptr)
530 {
531 microservice_impl* self = (microservice_impl*)thisptr;
532 return gate_atomic_int_inc(&self->refcounter);
533 }
534
535 #define MICROSERVICEBASE_CALL(thisptr, func_call) \
536 microservice_impl* self = (microservice_impl*)thisptr; \
537 if(!self->parent) return GATE_RESULT_INVALIDSTATE; \
538 try { \
539 self->parent-> func_call ; \
540 } \
541 catch(gate::Throwable const& xcpt) { \
542 return xcpt.getResult(); \
543 } \
544 catch(...) { \
545 return GATE_RESULT_UNKNOWNEXCEPTION; \
546 }
547
548 #define MICROSERVICEBASE_CALL_RET(thisptr, ret_var, func_call) \
549 microservice_impl* self = (microservice_impl*)thisptr; \
550 if(!self->parent) return GATE_RESULT_INVALIDSTATE; \
551 try { \
552 ret_var = self->parent-> func_call ; \
553 } \
554 catch(gate::Throwable const& xcpt) { \
555 return xcpt.getResult(); \
556 } \
557 catch(...) { \
558 return GATE_RESULT_UNKNOWNEXCEPTION; \
559 }
560
561
562 gate_result_t MicroServiceBase::msi_start(void* thisptr)
563 {
564 MICROSERVICEBASE_CALL(thisptr, onStart());
565 return GATE_RESULT_OK;
566 }
567 gate_result_t MicroServiceBase::msi_stop(void* thisptr)
568 {
569 MICROSERVICEBASE_CALL(thisptr, onStop());
570 return GATE_RESULT_OK;
571 }
572 gate_enumint_t MicroServiceBase::msi_get_status(void* thisptr)
573 {
574 microservice_impl* self = (microservice_impl*)thisptr;
575 if (!self->parent) return GATE_RESULT_INVALIDSTATE;
576 return (gate_enumint_t)self->parent->getStatus();
577 }
578
579 gate_result_t MicroServiceBase::msi_setup(void* thisptr, gate_string_t const* instance_address, gate_microhost_t* host)
580 {
581 String address(*instance_address);
582 MicroHost microhost(host);
583 gate_object_retain(host);
584
585 MICROSERVICEBASE_CALL(thisptr, setup(address, microhost));
586 return GATE_RESULT_OK;
587 }
588 gate_result_t MicroServiceBase::msi_get_address(void* thisptr, gate_string_t* ptr_output_address)
589 {
590 String address;
591 MICROSERVICEBASE_CALL_RET(thisptr, address, getAddress());
592 if (ptr_output_address)
593 {
594 gate_string_clone(ptr_output_address, address.c_impl());
595 }
596 return GATE_RESULT_OK;
597 }
598 gate_result_t MicroServiceBase::msi_get_condition_bits(void* thisptr, gate_enumint_t* ptr_bits)
599 {
600 enumint_t stat = 0;
601 MICROSERVICEBASE_CALL_RET(thisptr, stat, getConditionBits());
602 if (ptr_bits)
603 {
604 *ptr_bits = stat;
605 }
606 return GATE_RESULT_OK;
607 }
608
609 gate_result_t MicroServiceBase::msi_process_message(void* thisptr,
610 gate_string_t const* source_service_address, gate_string_t const* publish_channel,
611 gate_string_t const* msg_id, gate_string_t const* message, void* user_param)
612 {
613 String source(*source_service_address);
614 String channel(*publish_channel);
615 String id(*msg_id);
616 String msg(*message);
617
618 MICROSERVICEBASE_CALL(thisptr, onMessageReceived(source, channel, id, msg));
619 return GATE_RESULT_OK;
620 }
621
622 gate_result_t MicroServiceBase::msi_process_object(void* thisptr,
623 gate_string_t const* source_service_address, gate_string_t const* publish_channel,
624 gate_string_t const* obj_id, gate_object_t* ptr_object, void* user_param)
625 {
626 String source(*source_service_address);
627 String channel(*publish_channel);
628 String id(*obj_id);
629 Object obj(ptr_object);
630 gate_object_retain(ptr_object);
631
632 MICROSERVICEBASE_CALL(thisptr, onObjectReceived(source, channel, id, obj));
633 return GATE_RESULT_OK;
634 }
635
636 gate_result_t MicroServiceBase::msi_invoke(void* thisptr,
637 gate_string_t const* method, gate_struct_t const* request, gate_struct_t* response)
638 {
639 String methodName(*method);
640 ConstStruct requestStruct(request);
641 MutableStruct responseStruct(response);
642
643 MICROSERVICEBASE_CALL(thisptr, onInvoke(methodName, requestStruct, responseStruct));
644 return GATE_RESULT_OK;
645 }
646
647 gate_result_t MicroServiceBase::msi_get_parameter_names(void* thisptr, gate_array_t* ptr_output_names)
648 {
649 StringArray names;
650
651 MICROSERVICEBASE_CALL_RET(thisptr, names, getParameterNames());
652
653 if (ptr_output_names)
654 {
655 gate_array_duplicate(ptr_output_names, names.c_impl());
656 }
657 return GATE_RESULT_OK;
658 }
659
660 gate_result_t MicroServiceBase::msi_get_parameter_type(void* thisptr, gate_string_t const* name, gate_uint32_t* ptr_output_type)
661 {
662 //TODO
663 return GATE_RESULT_OK;
664 }
665
666 gate_result_t MicroServiceBase::msi_get_parameter(void* thisptr, gate_string_t const* name, gate_property_t* ptr_output_value)
667 {
668 //TODO
669 return GATE_RESULT_OK;
670 }
671
672 gate_result_t MicroServiceBase::msi_set_parameter(void* thisptr, gate_string_t const* name, gate_property_t const* value)
673 {
674 //TODO
675 return GATE_RESULT_OK;
676 }
677
678
679 /*********************************
680 * MicroFactory implementation *
681 *********************************/
682
683 MicroFactory::MicroFactory(gate_microfactory_t* impl) noexcept
684 : object_impl_t(impl)
685 {
686 }
687
688 MicroFactory::~MicroFactory() noexcept
689 {
690 }
691
692 Array<String> MicroFactory::getSupportedServiceNames()
693 {
694 Array<String> ret;
695 gate_array_t names = GATE_INIT_EMPTY;
696 result_t result = gate_microfactory_supported_service_names(this->c_impl(), &names);
697 GATEXX_CHECK_ERROR(result);
698 return util::createStringArray(names).toArray();
699 }
700
701 MicroService MicroFactory::createService(String const& serviceName)
702 {
703 gate_microservice_t* ptr_service = NULL;
704 result_t result = gate_microfactory_create_service(this->c_impl(), serviceName.c_impl(), &ptr_service);
705 GATEXX_CHECK_EXCEPTION(result);
706 return MicroService(ptr_service);
707 }
708
709
710
711
712 /*************************************
713 * MicroFactoryBase implementation *
714 *************************************/
715
716 MicroFactoryBase::MicroFactoryBase()
717 {
718 static GATE_INTERFACE_VTBL(gate_microfactory) local_vtbl = {
719 &MicroFactoryBase::mf_get_interface_name,
720 &MicroFactoryBase::mf_release,
721 &MicroFactoryBase::mf_retain,
722 &MicroFactoryBase::mf_supported_service_names,
723 &MicroFactoryBase::mf_create_service
724 };
725
726 this->impl.vtbl = &local_vtbl;
727 gate_atomic_int_init(&this->impl.refcounter, 0);
728 this->impl.parent = this;
729 }
730 MicroFactoryBase::~MicroFactoryBase() noexcept
731 {
732 }
733
734 MicroFactory MicroFactoryBase::getInstance()
735 {
736 MicroFactory factory(&this->impl);
737 gate_object_retain(&this->impl);
738 return factory;
739 }
740
741 char const* MicroFactoryBase::mf_get_interface_name(void* thisptr)
742 {
743 return GATE_INTERFACE_NAME_MICROFACTORY;
744 }
745 void MicroFactoryBase::mf_release(void* thisptr)
746 {
747 microfactory_impl* impl = (microfactory_impl*)thisptr;
748 if (gate_atomic_int_dec(&impl->refcounter) == 0)
749 {
750 MicroFactoryBase* ptr = impl->parent;
751 impl->parent = NULL;
752 delete ptr;
753 }
754 }
755 int MicroFactoryBase::mf_retain(void* thisptr)
756 {
757 microfactory_impl* impl = (microfactory_impl*)thisptr;
758 return gate_atomic_int_inc(&impl->refcounter);
759 }
760
761 gate_result_t MicroFactoryBase::mf_supported_service_names(void* thisptr, gate_array_t* ptr_output_names)
762 {
763 microfactory_impl* impl = (microfactory_impl*)thisptr;
764 MicroFactoryBase* ptr = impl->parent;
765 if (!ptr)
766 {
767 return GATE_RESULT_INVALIDSTATE;
768 }
769 StringArray names;
770 try
771 {
772 names = ptr->getSupportedServiceNames();
773 }
774 catch (Throwable const& xcpt)
775 {
776 return xcpt.getResult();
777 }
778 catch (...)
779 {
780 return GATE_RESULT_FAILED;
781 }
782 gate_arraylist_t names_list = gate::util::convertStringArray(names);
783 if (NULL == names_list)
784 {
785 return GATE_RESULT_OUTOFMEMORY;
786 }
787 gate_result_t ret = GATE_RESULT_OK;
788 if (ptr_output_names)
789 {
790 if (NULL == gate_array_create(ptr_output_names, names_list))
791 {
792 ret = GATE_RESULT_OUTOFMEMORY;
793 }
794 }
795 gate_arraylist_release(names_list);
796 return ret;
797 }
798
799 gate_result_t MicroFactoryBase::mf_create_service(void* thisptr, gate_string_t const* service_name, gate_microservice_t** ptr_service)
800 {
801 microfactory_impl* impl = (microfactory_impl*)thisptr;
802 MicroFactoryBase* ptr = impl->parent;
803 if (!ptr)
804 {
805 return GATE_RESULT_INVALIDSTATE;
806 }
807
808 gate_result_t ret = GATE_RESULT_FAILED;
809 try
810 {
811 String name(*service_name);
812 MicroService svc = ptr->createService(name);
813
814 if (ptr_service)
815 {
816 *ptr_service = svc.c_impl();
817 gate_object_retain(*ptr_service);
818 }
819 ret = GATE_RESULT_OK;
820 }
821 catch (Throwable const& xcpt)
822 {
823 ret = xcpt.getResult();
824 }
825 catch (...)
826 {
827 ret = GATE_RESULT_FAILED;
828 }
829 return ret;
830 }
831
832
833 } // end of namespace tech
834 } // end of namespace gate
835