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 |
|
|
|