Hazelcast C++ Client
Hazelcast C++ Client Library
Loading...
Searching...
No Matches
protocol.cpp
1/*
2 * Copyright (c) 2008-2025, Hazelcast, Inc. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <assert.h>
18
19#include <boost/uuid/uuid_io.hpp>
20
21#include "hazelcast/client/protocol/ClientMessage.h"
22#include <hazelcast/client/protocol/ClientProtocolErrorCodes.h>
23#include "hazelcast/util/ByteBuffer.h"
24#include "hazelcast/util/Util.h"
25#include "hazelcast/client/member.h"
26#include "hazelcast/client/protocol/ClientExceptionFactory.h"
27#include "hazelcast/client/protocol/codec/ErrorCodec.h"
28#include "hazelcast/client/exception/protocol_exceptions.h"
29#include "hazelcast/client/protocol/ClientMessageBuilder.h"
30#include "hazelcast/client/protocol/IMessageHandler.h"
31#include "hazelcast/client/connection/Connection.h"
32#include "hazelcast/client/protocol/UsernamePasswordCredentials.h"
33#include "hazelcast/cp/cp.h"
34#include "hazelcast/client/protocol/codec/builtin/custom_type_factory.h"
35#include "hazelcast/client/protocol/codec/builtin/sql_page_codec.h"
36
37namespace hazelcast {
38namespace client {
39namespace protocol {
40const std::string ClientTypes::CPP = "CPP";
41
42constexpr size_t ClientMessage::EXPECTED_DATA_BLOCK_SIZE;
43
44const ClientMessage::frame_header_type ClientMessage::NULL_FRAME{
45 ClientMessage::SIZE_OF_FRAME_LENGTH_AND_FLAGS,
46 ClientMessage::IS_NULL_FLAG
47};
48const ClientMessage::frame_header_type ClientMessage::BEGIN_FRAME{
49 ClientMessage::SIZE_OF_FRAME_LENGTH_AND_FLAGS,
50 ClientMessage::BEGIN_DATA_STRUCTURE_FLAG
51};
52const ClientMessage::frame_header_type ClientMessage::END_FRAME{
53 ClientMessage::SIZE_OF_FRAME_LENGTH_AND_FLAGS,
54 ClientMessage::END_DATA_STRUCTURE_FLAG
55};
56
57ClientMessage::ClientMessage()
58 : retryable_(false)
59 , contains_serialized_data_in_request_(false)
60{}
61
62ClientMessage::ClientMessage(size_t initial_frame_size, bool is_fingle_frame)
63 : retryable_(false)
64 , contains_serialized_data_in_request_(false)
65{
66 auto* initial_frame =
67 reinterpret_cast<frame_header_type*>(wr_ptr(REQUEST_HEADER_LEN));
68 initial_frame->frame_len = initial_frame_size;
69 initial_frame->flags =
70 is_fingle_frame
71 ? static_cast<int16_t>(ClientMessage::UNFRAGMENTED_MESSAGE) |
72 static_cast<int16_t>(ClientMessage::IS_FINAL_FLAG)
73 : ClientMessage::UNFRAGMENTED_MESSAGE;
74}
75
76void
77ClientMessage::wrap_for_read()
78{
79 buffer_index_ = 0;
80 offset_ = 0;
81}
82
83//----- Setter methods begin --------------------------------------
84void
85ClientMessage::set_message_type(int32_t type)
86{
87 boost::endian::
88 endian_store<boost::int64_t, 8, boost::endian::order::little>(
89 &data_buffer_[0][TYPE_FIELD_OFFSET], type);
90}
91
92void
93ClientMessage::set_correlation_id(int64_t id)
94{
95 boost::endian::
96 endian_store<boost::int64_t, 8, boost::endian::order::little>(
97 &data_buffer_[0][CORRELATION_ID_FIELD_OFFSET], id);
98}
99
100void
101ClientMessage::set_partition_id(int32_t partition_id)
102{
103 boost::endian::
104 endian_store<boost::int32_t, 4, boost::endian::order::little>(
105 &data_buffer_[0][PARTITION_ID_FIELD_OFFSET], partition_id);
106}
107
108template<>
109void
110ClientMessage::set(
111 const std::vector<std::pair<boost::uuids::uuid, int64_t>>& values,
112 bool is_final)
113{
114 auto* f =
115 reinterpret_cast<frame_header_type*>(wr_ptr(SIZE_OF_FRAME_LENGTH_AND_FLAGS));
116 f->frame_len =
117 values.size() * (UUID_SIZE + INT64_SIZE) + SIZE_OF_FRAME_LENGTH_AND_FLAGS;
118 f->flags = is_final ? IS_FINAL_FLAG : DEFAULT_FLAGS;
119 for (auto& p : values) {
120 set(p.first);
121 set(p.second);
122 }
123}
124
125template<>
126void
127ClientMessage::set(const std::vector<boost::uuids::uuid>& values, bool is_final)
128{
129 auto* h =
130 reinterpret_cast<frame_header_type*>(wr_ptr(SIZE_OF_FRAME_LENGTH_AND_FLAGS));
131 h->frame_len = SIZE_OF_FRAME_LENGTH_AND_FLAGS + values.size() * UUID_SIZE;
132 h->flags = is_final ? IS_FINAL_FLAG : DEFAULT_FLAGS;
133 for (auto& v : values) {
134 set(v);
135 }
136}
137
138template<>
139void
140ClientMessage::set(const std::vector<byte>& values, bool is_final)
141{
142 set_primitive_vector(values, is_final);
143}
144
145template<>
146void
147ClientMessage::set(const std::vector<int32_t>& values, bool is_final)
148{
149 set_primitive_vector(values, is_final);
150}
151
152template<>
153void
154ClientMessage::set(const std::vector<int64_t>& values, bool is_final)
155{
156 set_primitive_vector(values, is_final);
157}
158
159void
160ClientMessage::set(const query::anchor_data_list& list, bool is_final)
161{
162 add_begin_frame();
163 set(list.page_list);
164 set(list.data_list);
165 add_end_frame(is_final);
166}
167
168void
169ClientMessage::set(const codec::holder::paging_predicate_holder& p,
170 bool is_final)
171{
172 add_begin_frame();
173
174 auto f =
175 reinterpret_cast<frame_header_type*>(wr_ptr(SIZE_OF_FRAME_LENGTH_AND_FLAGS));
176 f->frame_len = SIZE_OF_FRAME_LENGTH_AND_FLAGS + 2 * INT32_SIZE + INT8_SIZE;
177 f->flags = DEFAULT_FLAGS;
178 set(p.page_size);
179 set(p.page);
180 set(p.iteration_type);
181
182 set(p.anchor_list);
183
184 set(p.predicate_data);
185 set(p.comparator_data);
186 set(static_cast<serialization::pimpl::data*>(nullptr));
187
188 add_end_frame(is_final);
189}
190
191//----- Setter methods end ---------------------
192
193void
194ClientMessage::fill_message_from(util::ByteBuffer& byte_buff,
195 bool& is_final,
196 size_t& remaining_bytes_in_frame)
197{
198 // Calculate the number of messages to read from the buffer first and then
199 // do read_bytes we add the frame sizes including the final frame to find
200 // the total. If there were bytes of a frame (remaining_bytes_in_frame) to
201 // read from the previous call, it is read.
202 auto remaining = byte_buff.remaining();
203 if (remaining_bytes_in_frame) {
204 size_t bytes_to_read = (std::min)(remaining_bytes_in_frame, remaining);
205 byte_buff.read_bytes(wr_ptr(bytes_to_read), bytes_to_read);
206 remaining_bytes_in_frame -= bytes_to_read;
207 if (remaining_bytes_in_frame > 0 || is_final) {
208 return;
209 }
210 }
211
212 remaining_bytes_in_frame = 0;
213 // more bytes to read
214 while (remaining_bytes_in_frame == 0 && !is_final &&
215 (remaining = byte_buff.remaining()) >=
216 ClientMessage::SIZE_OF_FRAME_LENGTH_AND_FLAGS) {
217 // start of the frame here
218 auto read_ptr = static_cast<byte*>(byte_buff.ix());
219 auto* f = reinterpret_cast<frame_header_type*>(read_ptr);
220 auto frame_len =
221 static_cast<size_t>(static_cast<int32_t>(f->frame_len));
222 is_final =
223 ClientMessage::is_flag_set(f->flags, ClientMessage::IS_FINAL_FLAG);
224 auto actual_bytes_to_read = (std::min)(frame_len, remaining);
225 byte_buff.read_bytes(wr_ptr(frame_len, actual_bytes_to_read),
226 actual_bytes_to_read);
227 remaining_bytes_in_frame = frame_len - actual_bytes_to_read;
228 }
229}
230
231size_t
232ClientMessage::size() const
233{
234 size_t len = 0;
235 for (auto& v : data_buffer_) {
236 len += v.size();
237 }
238 return len;
239}
240
241int32_t
242ClientMessage::get_message_type() const
243{
244 return boost::endian::
245 endian_load<boost::int32_t, 4, boost::endian::order::little>(
246 &data_buffer_[0][TYPE_FIELD_OFFSET]);
247}
248
249uint16_t
250ClientMessage::get_header_flags() const
251{
252 return boost::endian::
253 endian_load<boost::uint16_t, 2, boost::endian::order::little>(
254 &data_buffer_[0][FLAGS_FIELD_OFFSET]);
255}
256
257void
258ClientMessage::set_header_flags(uint16_t new_flags)
259{
260 return boost::endian::
261 endian_store<boost::uint16_t, 2, boost::endian::order::little>(
262 &data_buffer_[0][FLAGS_FIELD_OFFSET], new_flags);
263}
264
265int64_t
266ClientMessage::get_correlation_id() const
267{
268 return boost::endian::
269 endian_load<boost::int64_t, 8, boost::endian::order::little>(
270 &data_buffer_[0][CORRELATION_ID_FIELD_OFFSET]);
271}
272
273int8_t
274ClientMessage::get_number_of_backups() const
275{
276 return data_buffer_[0][RESPONSE_BACKUP_ACKS_FIELD_OFFSET];
277}
278
279int32_t
280ClientMessage::get_partition_id() const
281{
282 return boost::endian::
283 endian_load<boost::int32_t, 4, boost::endian::order::little>(
284 &data_buffer_[0][PARTITION_ID_FIELD_OFFSET]);
285}
286
287void
288ClientMessage::append(std::shared_ptr<ClientMessage> msg)
289{
290 // no need to double check if correlation ids match here,
291 // since we make sure that this is guaranteed at the caller that they are
292 // matching !
293 data_buffer_.insert(
294 data_buffer_.end(), msg->data_buffer_.begin(), msg->data_buffer_.end());
295}
296
297bool
298ClientMessage::is_retryable() const
299{
300 return retryable_;
301}
302
303void
304ClientMessage::set_retryable(bool should_retry)
305{
306 retryable_ = should_retry;
307}
308
309std::string
310ClientMessage::get_operation_name() const
311{
312 return operation_name_;
313}
314
315void
316ClientMessage::set_operation_name(const std::string& name)
317{
318 this->operation_name_ = name;
319}
320
321std::ostream&
322operator<<(std::ostream& os, const ClientMessage& msg)
323{
324 os << "ClientMessage{length=" << msg.size()
325 << ", operation=" << msg.get_operation_name()
326 << ", isRetryable=" << msg.is_retryable();
327
328 auto begin_fragment = msg.is_flag_set(ClientMessage::BEGIN_FRAGMENT_FLAG);
329 auto unfragmented = msg.is_flag_set(ClientMessage::UNFRAGMENTED_MESSAGE);
330
331 // print correlation id, and message type only if it is unfragmented message
332 // or the first message of a fragmented message
333 if (unfragmented) {
334 os << ", correlationId = " << msg.get_correlation_id()
335 << ", messageType = 0x" << std::hex << msg.get_message_type()
336 << std::dec << ", flags = 0x" << std::hex << msg.get_header_flags()
337 << std::dec << ", is backup aware = "
338 << ClientMessage::is_flag_set(msg.get_header_flags(),
339 ClientMessage::BACKUP_AWARE_FLAG)
340 << ", is backup event = "
341 << ClientMessage::is_flag_set(msg.get_header_flags(),
342 ClientMessage::BACKUP_EVENT_FLAG)
343 << ", isEvent = "
344 << ClientMessage::is_flag_set(msg.get_header_flags(),
345 ClientMessage::IS_EVENT_FLAG)
346 << "}";
347 } else if (begin_fragment) {
348 os << ", fragmentationId = "
349 << boost::endian::
350 endian_load<boost::int64_t, 8, boost::endian::order::little>(
351 &msg.data_buffer_[0][ClientMessage::FRAGMENTATION_ID_OFFSET])
352 << ", correlationId = " << msg.get_correlation_id()
353 << ", messageType = 0x" << std::hex << msg.get_message_type()
354 << std::dec << ", flags = 0x" << std::hex << msg.get_header_flags()
355 << std::dec << ", is backup aware = "
356 << ClientMessage::is_flag_set(msg.get_header_flags(),
357 ClientMessage::BACKUP_AWARE_FLAG)
358 << ", is backup event = "
359 << ClientMessage::is_flag_set(msg.get_header_flags(),
360 ClientMessage::BACKUP_EVENT_FLAG)
361 << ", isEvent = "
362 << ClientMessage::is_flag_set(msg.get_header_flags(),
363 ClientMessage::IS_EVENT_FLAG)
364 << "}";
365 } else {
366 os << ", fragmentationId = "
367 << boost::endian::
368 endian_load<boost::int64_t, 8, boost::endian::order::little>(
369 &msg.data_buffer_[0][ClientMessage::FRAGMENTATION_ID_OFFSET]);
370 }
371 os << ", is_fragmented = " << (unfragmented ? "no" : "yes");
372
373 return os;
374}
375
376void
377ClientMessage::set(unsigned char* /* memory */, boost::uuids::uuid uuid)
378{
379 std::memcpy(wr_ptr(uuid.size()), uuid.data, uuid.size());
380}
381
382void
383ClientMessage::fast_forward_to_end_frame()
384{
385 // We are starting from 1 because of the BEGIN_FRAME we read
386 // in the beginning of the decode method
387 int number_expected_frames = 1;
388 while (number_expected_frames) {
389 auto* f =
390 reinterpret_cast<frame_header_type*>(rd_ptr(sizeof(frame_header_type)));
391
392 int16_t flags = f->flags;
393 if (is_flag_set(flags, END_DATA_STRUCTURE_FLAG)) {
394 number_expected_frames--;
395 } else if (is_flag_set(flags, BEGIN_DATA_STRUCTURE_FLAG)) {
396 number_expected_frames++;
397 }
398
399 // skip current frame
400 rd_ptr(static_cast<int32_t>(f->frame_len) - sizeof(frame_header_type));
401 }
402}
403
404const std::vector<serialization::pimpl::schema>&
405ClientMessage::schemas_will_be_replicated() const
406{
407 return schemas_will_be_replicated_;
408}
409
410const ClientMessage::frame_header_type&
411ClientMessage::null_frame()
412{
413 return NULL_FRAME;
414}
415
416const ClientMessage::frame_header_type&
417ClientMessage::begin_frame()
418{
419 return BEGIN_FRAME;
420}
421
422const ClientMessage::frame_header_type&
423ClientMessage::end_frame()
424{
425 return END_FRAME;
426}
427
428void
429ClientMessage::drop_fragmentation_frame()
430{
431 data_buffer_[0].erase(data_buffer_[0].begin(),
432 data_buffer_[0].begin() + FRAGMENTATION_ID_OFFSET +
433 INT64_SIZE);
434}
435
436bool
437ClientMessage::contains_serialized_data_in_request() const
438{
439 return contains_serialized_data_in_request_;
440}
441
442void
443ClientMessage::set(const cp::raft_group_id& o, bool is_final)
444{
445 add_begin_frame();
446
447 auto f =
448 reinterpret_cast<frame_header_type*>(wr_ptr(SIZE_OF_FRAME_LENGTH_AND_FLAGS));
449 f->frame_len = SIZE_OF_FRAME_LENGTH_AND_FLAGS + 2 * INT64_SIZE;
450 f->flags = DEFAULT_FLAGS;
451 set(o.seed);
452 set(o.group_id);
453
454 set(o.name);
455
456 add_end_frame(is_final);
457}
458
459template<typename T>
460typename std::enable_if<std::is_same<T, cp::raft_group_id>::value, T>::type
461ClientMessage::get()
462{
463 // skip begin frame
464 rd_ptr(SIZE_OF_FRAME_LENGTH_AND_FLAGS);
465
466 // skip header of the frame
467 auto f =
468 reinterpret_cast<frame_header_type*>(rd_ptr(SIZE_OF_FRAME_LENGTH_AND_FLAGS));
469 auto seed = get<int64_t>();
470 auto id = get<int64_t>();
471 rd_ptr(static_cast<int32_t>(f->frame_len) - SIZE_OF_FRAME_LENGTH_AND_FLAGS -
472 2 * INT64_SIZE);
473
474 auto name = get<std::string>();
475
476 fast_forward_to_end_frame();
477
478 return { std::move(name), seed, id };
479}
480template cp::raft_group_id
481ClientMessage::get<cp::raft_group_id>();
482
483ExceptionFactory::~ExceptionFactory() = default;
484
485ClientExceptionFactory::ClientExceptionFactory()
486{
487 register_exception(
488 UNDEFINED, new ExceptionFactoryImpl<exception::undefined_error_code>());
489 register_exception(
490 ARRAY_INDEX_OUT_OF_BOUNDS,
491 new ExceptionFactoryImpl<exception::array_index_out_of_bounds>());
492 register_exception(ARRAY_STORE,
493 new ExceptionFactoryImpl<exception::array_store>());
494 register_exception(AUTHENTICATION,
495 new ExceptionFactoryImpl<exception::authentication>());
496 register_exception(CACHE_NOT_EXISTS,
497 new ExceptionFactoryImpl<exception::cache_not_exists>());
498 register_exception(
499 CALLER_NOT_MEMBER,
500 new ExceptionFactoryImpl<exception::caller_not_member>());
501 register_exception(CANCELLATION,
502 new ExceptionFactoryImpl<exception::cancellation>());
503 register_exception(CLASS_CAST,
504 new ExceptionFactoryImpl<exception::class_cast>());
505 register_exception(CLASS_NOT_FOUND,
506 new ExceptionFactoryImpl<exception::class_not_found>());
507 register_exception(
508 CONCURRENT_MODIFICATION,
509 new ExceptionFactoryImpl<exception::concurrent_modification>());
510 register_exception(CONFIG_MISMATCH,
511 new ExceptionFactoryImpl<exception::config_mismatch>());
512 register_exception(
513 DISTRIBUTED_OBJECT_DESTROYED,
514 new ExceptionFactoryImpl<exception::distributed_object_destroyed>());
515 register_exception(ENDOFFILE, new ExceptionFactoryImpl<exception::eof>());
516 register_exception(EXECUTION,
517 new ExceptionFactoryImpl<exception::execution>());
518 register_exception(HAZELCAST,
519 new ExceptionFactoryImpl<exception::hazelcast_>());
520 register_exception(
521 HAZELCAST_INSTANCE_NOT_ACTIVE,
522 new ExceptionFactoryImpl<exception::hazelcast_instance_not_active>());
523 register_exception(
524 HAZELCAST_OVERLOAD,
525 new ExceptionFactoryImpl<exception::hazelcast_overload>());
526 register_exception(
527 HAZELCAST_SERIALIZATION,
528 new ExceptionFactoryImpl<exception::hazelcast_serialization>());
529 register_exception(IO, new ExceptionFactoryImpl<exception::io>());
530 register_exception(ILLEGAL_ARGUMENT,
531 new ExceptionFactoryImpl<exception::illegal_argument>());
532 register_exception(ILLEGAL_ACCESS_EXCEPTION,
533 new ExceptionFactoryImpl<exception::illegal_access>());
534 register_exception(
535 ILLEGAL_ACCESS_ERROR,
536 new ExceptionFactoryImpl<exception::illegal_access_error>());
537 register_exception(
538 ILLEGAL_MONITOR_STATE,
539 new ExceptionFactoryImpl<exception::illegal_monitor_state>());
540 register_exception(ILLEGAL_STATE,
541 new ExceptionFactoryImpl<exception::illegal_state>());
542 register_exception(
543 ILLEGAL_THREAD_STATE,
544 new ExceptionFactoryImpl<exception::illegal_thread_state>());
545 register_exception(
546 INDEX_OUT_OF_BOUNDS,
547 new ExceptionFactoryImpl<exception::index_out_of_bounds>());
548 register_exception(INTERRUPTED,
549 new ExceptionFactoryImpl<exception::interrupted>());
550 register_exception(INVALID_ADDRESS,
551 new ExceptionFactoryImpl<exception::invalid_address>());
552 register_exception(
553 INVALID_CONFIGURATION,
554 new ExceptionFactoryImpl<exception::invalid_configuration>());
555 register_exception(MEMBER_LEFT,
556 new ExceptionFactoryImpl<exception::member_left>());
557 register_exception(
558 NEGATIVE_ARRAY_SIZE,
559 new ExceptionFactoryImpl<exception::negative_array_size>());
560 register_exception(NO_SUCH_ELEMENT,
561 new ExceptionFactoryImpl<exception::no_such_element>());
562 register_exception(NOT_SERIALIZABLE,
563 new ExceptionFactoryImpl<exception::not_serializable>());
564 register_exception(NULL_POINTER,
565 new ExceptionFactoryImpl<exception::null_pointer>());
566 register_exception(
567 OPERATION_TIMEOUT,
568 new ExceptionFactoryImpl<exception::operation_timeout>());
569 register_exception(
570 PARTITION_MIGRATING,
571 new ExceptionFactoryImpl<exception::partition_migrating>());
572 register_exception(QUERY, new ExceptionFactoryImpl<exception::query>());
573 register_exception(
574 QUERY_RESULT_SIZE_EXCEEDED,
575 new ExceptionFactoryImpl<exception::query_result_size_exceeded>());
576 register_exception(REACHED_MAX_SIZE,
577 new ExceptionFactoryImpl<exception::reached_max_size>());
578 register_exception(
579 REJECTED_EXECUTION,
580 new ExceptionFactoryImpl<exception::rejected_execution>());
581 register_exception(
582 RESPONSE_ALREADY_SENT,
583 new ExceptionFactoryImpl<exception::response_already_sent>());
584 register_exception(
585 RETRYABLE_HAZELCAST,
586 new ExceptionFactoryImpl<exception::retryable_hazelcast>());
587 register_exception(RETRYABLE_IO,
588 new ExceptionFactoryImpl<exception::retryable_io>());
589 register_exception(RUNTIME, new ExceptionFactoryImpl<exception::runtime>());
590 register_exception(
591 SECURITY, new ExceptionFactoryImpl<exception::SecurityException>());
592 register_exception(SOCK_ERROR,
593 new ExceptionFactoryImpl<exception::socket>());
594 register_exception(STALE_SEQUENCE,
595 new ExceptionFactoryImpl<exception::stale_sequence>());
596 register_exception(
597 TARGET_DISCONNECTED,
598 new ExceptionFactoryImpl<exception::target_disconnected>());
599 register_exception(
600 TARGET_NOT_MEMBER,
601 new ExceptionFactoryImpl<exception::target_not_member>());
602 register_exception(TIMEOUT, new ExceptionFactoryImpl<exception::timeout>());
603 register_exception(TOPIC_OVERLOAD,
604 new ExceptionFactoryImpl<exception::topic_overload>());
605 register_exception(TRANSACTION,
606 new ExceptionFactoryImpl<exception::transaction>());
607 register_exception(
608 TRANSACTION_NOT_ACTIVE,
609 new ExceptionFactoryImpl<exception::transaction_not_active>());
610 register_exception(
611 TRANSACTION_TIMED_OUT,
612 new ExceptionFactoryImpl<exception::transaction_timed_out>());
613 register_exception(URI_SYNTAX,
614 new ExceptionFactoryImpl<exception::uri_syntax>());
615 register_exception(UTF_DATA_FORMAT,
616 new ExceptionFactoryImpl<exception::utf_data_format>());
617 register_exception(
618 UNSUPPORTED_OPERATION,
619 new ExceptionFactoryImpl<exception::unsupported_operation>());
620 register_exception(WRONG_TARGET,
621 new ExceptionFactoryImpl<exception::wrong_target>());
622 register_exception(XA, new ExceptionFactoryImpl<exception::xa>());
623 register_exception(ACCESS_CONTROL,
624 new ExceptionFactoryImpl<exception::access_control>());
625 register_exception(LOGIN, new ExceptionFactoryImpl<exception::login>());
626 register_exception(
627 UNSUPPORTED_CALLBACK,
628 new ExceptionFactoryImpl<exception::unsupported_callback>());
629 register_exception(
630 NO_DATA_MEMBER,
631 new ExceptionFactoryImpl<exception::no_data_member_in_cluster>());
632 register_exception(
633 REPLICATED_MAP_CANT_BE_CREATED,
634 new ExceptionFactoryImpl<
635 exception::replicated_map_cant_be_created_on_lite_member>());
636 register_exception(
637 MAX_MESSAGE_SIZE_EXCEEDED,
638 new ExceptionFactoryImpl<exception::max_message_size_exceeded>());
639 register_exception(
640 WAN_REPLICATION_QUEUE_FULL,
641 new ExceptionFactoryImpl<exception::wan_replication_queue_full>());
642 register_exception(ASSERTION_ERROR,
643 new ExceptionFactoryImpl<exception::assertion_error>());
644 register_exception(
645 OUT_OF_MEMORY_ERROR,
646 new ExceptionFactoryImpl<exception::out_of_memory_error>());
647 register_exception(
648 STACK_OVERFLOW_ERROR,
649 new ExceptionFactoryImpl<exception::stack_overflow_error>());
650 register_exception(
651 NATIVE_OUT_OF_MEMORY_ERROR,
652 new ExceptionFactoryImpl<exception::native_out_of_memory_error>());
653 register_exception(
654 SERVICE_NOT_FOUND,
655 new ExceptionFactoryImpl<exception::service_not_found>());
656 register_exception(STALE_TASK_ID,
657 new ExceptionFactoryImpl<exception::stale_task_id>());
658 register_exception(DUPLICATE_TASK,
659 new ExceptionFactoryImpl<exception::duplicate_task>());
660 register_exception(STALE_TASK,
661 new ExceptionFactoryImpl<exception::stale_task>());
662 register_exception(
663 LOCAL_MEMBER_RESET,
664 new ExceptionFactoryImpl<exception::local_member_reset>());
665 register_exception(
666 INDETERMINATE_OPERATION_STATE,
667 new ExceptionFactoryImpl<exception::indeterminate_operation_state>());
668 register_exception(
669 FLAKE_ID_NODE_ID_OUT_OF_RANGE_EXCEPTION,
670 new ExceptionFactoryImpl<exception::node_id_out_of_range>());
671 register_exception(
672 TARGET_NOT_REPLICA_EXCEPTION,
673 new ExceptionFactoryImpl<exception::target_not_replica>());
674 register_exception(
675 MUTATION_DISALLOWED_EXCEPTION,
676 new ExceptionFactoryImpl<exception::mutation_disallowed>());
677 register_exception(CONSISTENCY_LOST_EXCEPTION,
678 new ExceptionFactoryImpl<exception::consistency_lost>());
679 register_exception(SESSION_EXPIRED_EXCEPTION,
680 new ExceptionFactoryImpl<exception::session_expired>());
681 register_exception(
682 WAIT_KEY_CANCELLED_EXCEPTION,
683 new ExceptionFactoryImpl<exception::wait_key_cancelled>());
684 register_exception(
685 LOCK_ACQUIRE_LIMIT_REACHED_EXCEPTION,
686 new ExceptionFactoryImpl<exception::lock_acquire_limit_reached>());
687 register_exception(
688 LOCK_OWNERSHIP_LOST_EXCEPTION,
689 new ExceptionFactoryImpl<exception::lock_ownership_lost>());
690 register_exception(
691 CP_GROUP_DESTROYED_EXCEPTION,
692 new ExceptionFactoryImpl<exception::cp_group_destroyed>());
693 register_exception(CANNOT_REPLICATE_EXCEPTION,
694 new ExceptionFactoryImpl<exception::cannot_replicate>());
695 register_exception(LEADER_DEMOTED_EXCEPTION,
696 new ExceptionFactoryImpl<exception::leader_demoted>());
697 register_exception(
698 STALE_APPEND_REQUEST_EXCEPTION,
699 new ExceptionFactoryImpl<exception::stale_append_request>());
700 register_exception(NOT_LEADER_EXCEPTION,
701 new ExceptionFactoryImpl<exception::not_leader>());
702 register_exception(VERSION_MISMATCH_EXCEPTION,
703 new ExceptionFactoryImpl<exception::version_mismatch>());
704}
705
706ClientExceptionFactory::~ClientExceptionFactory()
707{
708 // release memory for the factories
709 for (std::unordered_map<
710 int,
711 hazelcast::client::protocol::ExceptionFactory*>::const_iterator it =
712 error_code_to_factory_.begin();
713 error_code_to_factory_.end() != it;
714 ++it) {
715 delete (it->second);
716 }
717}
718
719void
720ClientExceptionFactory::register_exception(int32_t error_code,
721 ExceptionFactory* factory)
722{
723 auto it = error_code_to_factory_.find(error_code);
724 if (error_code_to_factory_.end() != it) {
725 char msg[100];
726 util::hz_snprintf(
727 msg, 100, "Error code %d was already registered!!!", error_code);
728 BOOST_THROW_EXCEPTION(exception::illegal_state(
729 "ClientExceptionFactory::registerException", msg));
730 }
731
732 error_code_to_factory_[error_code] = factory;
733}
734
735std::exception_ptr
736ClientExceptionFactory::create_exception(
737 std::vector<codec::ErrorHolder>::const_iterator begin,
738 std::vector<codec::ErrorHolder>::const_iterator end) const
739{
740 if (begin == end) {
741 return nullptr;
742 }
743 auto factory = error_code_to_factory_.find(begin->error_code);
744 if (error_code_to_factory_.end() == factory) {
745 factory = error_code_to_factory_.find(
746 protocol::client_protocol_error_codes::UNDEFINED);
747 }
748 return factory->second->create_exception(*this,
749 begin->class_name,
750 begin->message.value_or("nullptr"),
751 begin->to_string(),
752 create_exception(begin + 1, end));
753}
754
755std::exception_ptr
756ClientExceptionFactory::create_exception(
757 const std::vector<codec::ErrorHolder>& errors) const
758{
759 return create_exception(errors.begin(), errors.end());
760}
761
762UsernamePasswordCredentials::UsernamePasswordCredentials(
763 const std::string& principal,
764 const std::string& password)
765 : name_(principal)
766 , password_(password)
767{}
768
769const std::string&
770UsernamePasswordCredentials::get_name() const
771{
772 return name_;
773}
774
775const std::string&
776UsernamePasswordCredentials::get_password() const
777{
778 return password_;
779}
780
781namespace codec {
782std::ostream&
783operator<<(std::ostream& out, const StackTraceElement& trace)
784{
785 return out << trace.file_name << " line " << trace.line_number << " :"
786 << trace.declaring_class << "." << trace.method_name;
787}
788
789std::vector<ErrorHolder>
790ErrorCodec::decode(ClientMessage& msg)
791{
792 // skip initial message frame
793 msg.skip_frame();
794
795 return msg.get<std::vector<ErrorHolder>>();
796}
797
798std::string
799ErrorHolder::to_string() const
800{
801 std::ostringstream out;
802 out << "Error code:" << error_code
803 << ", Class name that generated the error:" << class_name << ", ";
804 if (message) {
805 out << *message;
806 }
807 out << std::endl;
808 for (auto s : stack_trace) {
809 out << "\t" << s << std::endl;
810 }
811
812 return out.str();
813}
814
815namespace builtin {
816sql::sql_column_metadata
817custom_type_factory::create_sql_column_metadata(std::string name,
818 int32_t type,
819 bool is_nullable_exists,
820 bool nullability)
821{
822 using namespace hazelcast::client::sql;
823 if (type < static_cast<int32_t>(sql_column_type::varchar) ||
824 type > static_cast<int32_t>(sql_column_type::json)) {
825 throw hazelcast::client::exception::hazelcast_(
826 "custom_type_factory::create_sql_column_metadata",
827 (boost::format("Unexpected SQL column type = [%1%]") % type).str());
828 }
829
830 if (is_nullable_exists) {
831 return sql_column_metadata{
832 std::move(name), static_cast<sql_column_type>(type), nullability};
833 }
834
835 return sql_column_metadata{
836 std::move(name), static_cast<sql_column_type>(type), true};
837}
838
839std::shared_ptr<sql::sql_page>
840sql_page_codec::decode(ClientMessage& msg,
841 std::shared_ptr<sql::sql_row_metadata> row_metadata)
842{
843 // begin frame
844 msg.skip_frame();
845
846 bool last =
847 msg.peek(ClientMessage::SIZE_OF_FRAME_LENGTH_AND_FLAGS +
848 1)[ClientMessage::SIZE_OF_FRAME_LENGTH_AND_FLAGS] == 1;
849
850 msg.skip_frame();
851
852 auto column_type_ids = msg.get<std::vector<int32_t>>();
853
854 using column = std::vector<boost::any>;
855
856 using namespace sql;
857
858 auto number_of_columns = column_type_ids.size();
859 std::vector<column> columns(number_of_columns);
860 std::vector<sql_column_type> column_types(number_of_columns);
861
862 for (std::size_t i = 0; i < number_of_columns; ++i) {
863 auto column_type = static_cast<sql_column_type>(column_type_ids[i]);
864 column_types[i] = column_type;
865 columns[i] = sql_page_codec::decode_column_values(msg, column_type);
866 }
867
868 msg.fast_forward_to_end_frame();
869
870 auto page = std::make_shared<sql::sql_page>(
871 std::move(column_types), std::move(columns), last, row_metadata);
872 // se have to construct the rows properly
873 page->construct_rows();
874 return page;
875}
876std::vector<boost::any>
877sql_page_codec::decode_column_values(ClientMessage& msg,
878 sql::sql_column_type column_type)
879{
880 switch (column_type) {
881 case sql::sql_column_type::varchar:
882 return to_vector_of_any(
883 msg.get<std::vector<boost::optional<std::string>>>());
884 case sql::sql_column_type::boolean:
885 return to_vector_of_any(
886 builtin::list_cn_fixed_size_codec::decode<bool>(msg));
887 case sql::sql_column_type::tinyint:
888 return to_vector_of_any(
889 builtin::list_cn_fixed_size_codec::decode<byte>(msg));
890 case sql::sql_column_type::smallint:
891 return to_vector_of_any(
892 builtin::list_cn_fixed_size_codec::decode<int16_t>(msg));
893 case sql::sql_column_type::integer:
894 return to_vector_of_any(
895 builtin::list_cn_fixed_size_codec::decode<int32_t>(msg));
896 case sql::sql_column_type::bigint:
897 return to_vector_of_any(
898 builtin::list_cn_fixed_size_codec::decode<int64_t>(msg));
899 case sql::sql_column_type::real:
900 return to_vector_of_any(
901 builtin::list_cn_fixed_size_codec::decode<float>(msg));
902 case sql::sql_column_type::double_:
903 return to_vector_of_any(
904 builtin::list_cn_fixed_size_codec::decode<double>(msg));
905 case sql::sql_column_type::date:
906 return to_vector_of_any(
907 builtin::list_cn_fixed_size_codec::decode<local_date>(
908 msg));
909 case sql::sql_column_type::time:
910 return to_vector_of_any(
911 builtin::list_cn_fixed_size_codec::decode<local_time>(
912 msg));
913 case sql::sql_column_type::timestamp:
914 return to_vector_of_any(
915 builtin::list_cn_fixed_size_codec::decode<
916 local_date_time>(msg));
917 case sql::sql_column_type::timestamp_with_timezone:
918 return to_vector_of_any(
919 builtin::list_cn_fixed_size_codec::decode<
920 offset_date_time>(msg));
921 case sql::sql_column_type::decimal:
922 return to_vector_of_any(
923 builtin::list_cn_fixed_size_codec::decode<big_decimal>(
924 msg));
925 case sql::sql_column_type::null: {
926 msg.skip_frame_header_bytes();
927
928 auto size = msg.get<int32_t>();
929 return
930 std::vector<boost::any>(static_cast<size_t>(size));
931 }
932 case sql::sql_column_type::object:
933 return to_vector_of_any(
934 msg.get<std::vector<
935 boost::optional<serialization::pimpl::data>>>());
936 case sql::sql_column_type::json:
937 return to_vector_of_any(
938 msg.get<std::vector<boost::optional<hazelcast_json_value>>>());
939 default:
940 throw exception::illegal_state(
941 "ClientMessage::get<sql::sql_page>",
942 (boost::format("Unknown type %1%") %
943 static_cast<int32_t>(column_type))
944 .str());
945 }
946
947}
948
949} // namespace builtin
950} // namespace codec
951} // namespace protocol
952} // namespace client
953} // namespace hazelcast
A date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30.
A date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system, such as 2007-12-03T10:...