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 static_assert(uuid.size() == util::Bits::UUID_SIZE_IN_BYTES, "uuid size must be 16");
380 std::memcpy(wr_ptr(uuid.size()), &uuid.data[0], uuid.size());
381}
382
383void
384ClientMessage::fast_forward_to_end_frame()
385{
386 // We are starting from 1 because of the BEGIN_FRAME we read
387 // in the beginning of the decode method
388 int number_expected_frames = 1;
389 while (number_expected_frames) {
390 auto* f =
391 reinterpret_cast<frame_header_type*>(rd_ptr(sizeof(frame_header_type)));
392
393 int16_t flags = f->flags;
394 if (is_flag_set(flags, END_DATA_STRUCTURE_FLAG)) {
395 number_expected_frames--;
396 } else if (is_flag_set(flags, BEGIN_DATA_STRUCTURE_FLAG)) {
397 number_expected_frames++;
398 }
399
400 // skip current frame
401 rd_ptr(static_cast<int32_t>(f->frame_len) - sizeof(frame_header_type));
402 }
403}
404
405const std::vector<serialization::pimpl::schema>&
406ClientMessage::schemas_will_be_replicated() const
407{
408 return schemas_will_be_replicated_;
409}
410
411const ClientMessage::frame_header_type&
412ClientMessage::null_frame()
413{
414 return NULL_FRAME;
415}
416
417const ClientMessage::frame_header_type&
418ClientMessage::begin_frame()
419{
420 return BEGIN_FRAME;
421}
422
423const ClientMessage::frame_header_type&
424ClientMessage::end_frame()
425{
426 return END_FRAME;
427}
428
429void
430ClientMessage::drop_fragmentation_frame()
431{
432 data_buffer_[0].erase(data_buffer_[0].begin(),
433 data_buffer_[0].begin() + FRAGMENTATION_ID_OFFSET +
434 INT64_SIZE);
435}
436
437bool
438ClientMessage::contains_serialized_data_in_request() const
439{
440 return contains_serialized_data_in_request_;
441}
442
443void
444ClientMessage::set(const cp::raft_group_id& o, bool is_final)
445{
446 add_begin_frame();
447
448 auto f =
449 reinterpret_cast<frame_header_type*>(wr_ptr(SIZE_OF_FRAME_LENGTH_AND_FLAGS));
450 f->frame_len = SIZE_OF_FRAME_LENGTH_AND_FLAGS + 2 * INT64_SIZE;
451 f->flags = DEFAULT_FLAGS;
452 set(o.seed);
453 set(o.group_id);
454
455 set(o.name);
456
457 add_end_frame(is_final);
458}
459
460template<typename T>
461typename std::enable_if<std::is_same<T, cp::raft_group_id>::value, T>::type
462ClientMessage::get()
463{
464 // skip begin frame
465 rd_ptr(SIZE_OF_FRAME_LENGTH_AND_FLAGS);
466
467 // skip header of the frame
468 auto f =
469 reinterpret_cast<frame_header_type*>(rd_ptr(SIZE_OF_FRAME_LENGTH_AND_FLAGS));
470 auto seed = get<int64_t>();
471 auto id = get<int64_t>();
472 rd_ptr(static_cast<int32_t>(f->frame_len) - SIZE_OF_FRAME_LENGTH_AND_FLAGS -
473 2 * INT64_SIZE);
474
475 auto name = get<std::string>();
476
477 fast_forward_to_end_frame();
478
479 return { std::move(name), seed, id };
480}
481template cp::raft_group_id
482ClientMessage::get<cp::raft_group_id>();
483
484ExceptionFactory::~ExceptionFactory() = default;
485
486ClientExceptionFactory::ClientExceptionFactory()
487{
488 register_exception(
489 UNDEFINED, new ExceptionFactoryImpl<exception::undefined_error_code>());
490 register_exception(
491 ARRAY_INDEX_OUT_OF_BOUNDS,
492 new ExceptionFactoryImpl<exception::array_index_out_of_bounds>());
493 register_exception(ARRAY_STORE,
494 new ExceptionFactoryImpl<exception::array_store>());
495 register_exception(AUTHENTICATION,
496 new ExceptionFactoryImpl<exception::authentication>());
497 register_exception(CACHE_NOT_EXISTS,
498 new ExceptionFactoryImpl<exception::cache_not_exists>());
499 register_exception(
500 CALLER_NOT_MEMBER,
501 new ExceptionFactoryImpl<exception::caller_not_member>());
502 register_exception(CANCELLATION,
503 new ExceptionFactoryImpl<exception::cancellation>());
504 register_exception(CLASS_CAST,
505 new ExceptionFactoryImpl<exception::class_cast>());
506 register_exception(CLASS_NOT_FOUND,
507 new ExceptionFactoryImpl<exception::class_not_found>());
508 register_exception(
509 CONCURRENT_MODIFICATION,
510 new ExceptionFactoryImpl<exception::concurrent_modification>());
511 register_exception(CONFIG_MISMATCH,
512 new ExceptionFactoryImpl<exception::config_mismatch>());
513 register_exception(
514 DISTRIBUTED_OBJECT_DESTROYED,
515 new ExceptionFactoryImpl<exception::distributed_object_destroyed>());
516 register_exception(ENDOFFILE, new ExceptionFactoryImpl<exception::eof>());
517 register_exception(EXECUTION,
518 new ExceptionFactoryImpl<exception::execution>());
519 register_exception(HAZELCAST,
520 new ExceptionFactoryImpl<exception::hazelcast_>());
521 register_exception(
522 HAZELCAST_INSTANCE_NOT_ACTIVE,
523 new ExceptionFactoryImpl<exception::hazelcast_instance_not_active>());
524 register_exception(
525 HAZELCAST_OVERLOAD,
526 new ExceptionFactoryImpl<exception::hazelcast_overload>());
527 register_exception(
528 HAZELCAST_SERIALIZATION,
529 new ExceptionFactoryImpl<exception::hazelcast_serialization>());
530 register_exception(IO, new ExceptionFactoryImpl<exception::io>());
531 register_exception(ILLEGAL_ARGUMENT,
532 new ExceptionFactoryImpl<exception::illegal_argument>());
533 register_exception(ILLEGAL_ACCESS_EXCEPTION,
534 new ExceptionFactoryImpl<exception::illegal_access>());
535 register_exception(
536 ILLEGAL_ACCESS_ERROR,
537 new ExceptionFactoryImpl<exception::illegal_access_error>());
538 register_exception(
539 ILLEGAL_MONITOR_STATE,
540 new ExceptionFactoryImpl<exception::illegal_monitor_state>());
541 register_exception(ILLEGAL_STATE,
542 new ExceptionFactoryImpl<exception::illegal_state>());
543 register_exception(
544 ILLEGAL_THREAD_STATE,
545 new ExceptionFactoryImpl<exception::illegal_thread_state>());
546 register_exception(
547 INDEX_OUT_OF_BOUNDS,
548 new ExceptionFactoryImpl<exception::index_out_of_bounds>());
549 register_exception(INTERRUPTED,
550 new ExceptionFactoryImpl<exception::interrupted>());
551 register_exception(INVALID_ADDRESS,
552 new ExceptionFactoryImpl<exception::invalid_address>());
553 register_exception(
554 INVALID_CONFIGURATION,
555 new ExceptionFactoryImpl<exception::invalid_configuration>());
556 register_exception(MEMBER_LEFT,
557 new ExceptionFactoryImpl<exception::member_left>());
558 register_exception(
559 NEGATIVE_ARRAY_SIZE,
560 new ExceptionFactoryImpl<exception::negative_array_size>());
561 register_exception(NO_SUCH_ELEMENT,
562 new ExceptionFactoryImpl<exception::no_such_element>());
563 register_exception(NOT_SERIALIZABLE,
564 new ExceptionFactoryImpl<exception::not_serializable>());
565 register_exception(NULL_POINTER,
566 new ExceptionFactoryImpl<exception::null_pointer>());
567 register_exception(
568 OPERATION_TIMEOUT,
569 new ExceptionFactoryImpl<exception::operation_timeout>());
570 register_exception(
571 PARTITION_MIGRATING,
572 new ExceptionFactoryImpl<exception::partition_migrating>());
573 register_exception(QUERY, new ExceptionFactoryImpl<exception::query>());
574 register_exception(
575 QUERY_RESULT_SIZE_EXCEEDED,
576 new ExceptionFactoryImpl<exception::query_result_size_exceeded>());
577 register_exception(REACHED_MAX_SIZE,
578 new ExceptionFactoryImpl<exception::reached_max_size>());
579 register_exception(
580 REJECTED_EXECUTION,
581 new ExceptionFactoryImpl<exception::rejected_execution>());
582 register_exception(
583 RESPONSE_ALREADY_SENT,
584 new ExceptionFactoryImpl<exception::response_already_sent>());
585 register_exception(
586 RETRYABLE_HAZELCAST,
587 new ExceptionFactoryImpl<exception::retryable_hazelcast>());
588 register_exception(RETRYABLE_IO,
589 new ExceptionFactoryImpl<exception::retryable_io>());
590 register_exception(RUNTIME, new ExceptionFactoryImpl<exception::runtime>());
591 register_exception(
592 SECURITY, new ExceptionFactoryImpl<exception::SecurityException>());
593 register_exception(SOCK_ERROR,
594 new ExceptionFactoryImpl<exception::socket>());
595 register_exception(STALE_SEQUENCE,
596 new ExceptionFactoryImpl<exception::stale_sequence>());
597 register_exception(
598 TARGET_DISCONNECTED,
599 new ExceptionFactoryImpl<exception::target_disconnected>());
600 register_exception(
601 TARGET_NOT_MEMBER,
602 new ExceptionFactoryImpl<exception::target_not_member>());
603 register_exception(TIMEOUT, new ExceptionFactoryImpl<exception::timeout>());
604 register_exception(TOPIC_OVERLOAD,
605 new ExceptionFactoryImpl<exception::topic_overload>());
606 register_exception(TRANSACTION,
607 new ExceptionFactoryImpl<exception::transaction>());
608 register_exception(
609 TRANSACTION_NOT_ACTIVE,
610 new ExceptionFactoryImpl<exception::transaction_not_active>());
611 register_exception(
612 TRANSACTION_TIMED_OUT,
613 new ExceptionFactoryImpl<exception::transaction_timed_out>());
614 register_exception(URI_SYNTAX,
615 new ExceptionFactoryImpl<exception::uri_syntax>());
616 register_exception(UTF_DATA_FORMAT,
617 new ExceptionFactoryImpl<exception::utf_data_format>());
618 register_exception(
619 UNSUPPORTED_OPERATION,
620 new ExceptionFactoryImpl<exception::unsupported_operation>());
621 register_exception(WRONG_TARGET,
622 new ExceptionFactoryImpl<exception::wrong_target>());
623 register_exception(XA, new ExceptionFactoryImpl<exception::xa>());
624 register_exception(ACCESS_CONTROL,
625 new ExceptionFactoryImpl<exception::access_control>());
626 register_exception(LOGIN, new ExceptionFactoryImpl<exception::login>());
627 register_exception(
628 UNSUPPORTED_CALLBACK,
629 new ExceptionFactoryImpl<exception::unsupported_callback>());
630 register_exception(
631 NO_DATA_MEMBER,
632 new ExceptionFactoryImpl<exception::no_data_member_in_cluster>());
633 register_exception(
634 REPLICATED_MAP_CANT_BE_CREATED,
635 new ExceptionFactoryImpl<
636 exception::replicated_map_cant_be_created_on_lite_member>());
637 register_exception(
638 MAX_MESSAGE_SIZE_EXCEEDED,
639 new ExceptionFactoryImpl<exception::max_message_size_exceeded>());
640 register_exception(
641 WAN_REPLICATION_QUEUE_FULL,
642 new ExceptionFactoryImpl<exception::wan_replication_queue_full>());
643 register_exception(ASSERTION_ERROR,
644 new ExceptionFactoryImpl<exception::assertion_error>());
645 register_exception(
646 OUT_OF_MEMORY_ERROR,
647 new ExceptionFactoryImpl<exception::out_of_memory_error>());
648 register_exception(
649 STACK_OVERFLOW_ERROR,
650 new ExceptionFactoryImpl<exception::stack_overflow_error>());
651 register_exception(
652 NATIVE_OUT_OF_MEMORY_ERROR,
653 new ExceptionFactoryImpl<exception::native_out_of_memory_error>());
654 register_exception(
655 SERVICE_NOT_FOUND,
656 new ExceptionFactoryImpl<exception::service_not_found>());
657 register_exception(STALE_TASK_ID,
658 new ExceptionFactoryImpl<exception::stale_task_id>());
659 register_exception(DUPLICATE_TASK,
660 new ExceptionFactoryImpl<exception::duplicate_task>());
661 register_exception(STALE_TASK,
662 new ExceptionFactoryImpl<exception::stale_task>());
663 register_exception(
664 LOCAL_MEMBER_RESET,
665 new ExceptionFactoryImpl<exception::local_member_reset>());
666 register_exception(
667 INDETERMINATE_OPERATION_STATE,
668 new ExceptionFactoryImpl<exception::indeterminate_operation_state>());
669 register_exception(
670 FLAKE_ID_NODE_ID_OUT_OF_RANGE_EXCEPTION,
671 new ExceptionFactoryImpl<exception::node_id_out_of_range>());
672 register_exception(
673 TARGET_NOT_REPLICA_EXCEPTION,
674 new ExceptionFactoryImpl<exception::target_not_replica>());
675 register_exception(
676 MUTATION_DISALLOWED_EXCEPTION,
677 new ExceptionFactoryImpl<exception::mutation_disallowed>());
678 register_exception(CONSISTENCY_LOST_EXCEPTION,
679 new ExceptionFactoryImpl<exception::consistency_lost>());
680 register_exception(SESSION_EXPIRED_EXCEPTION,
681 new ExceptionFactoryImpl<exception::session_expired>());
682 register_exception(
683 WAIT_KEY_CANCELLED_EXCEPTION,
684 new ExceptionFactoryImpl<exception::wait_key_cancelled>());
685 register_exception(
686 LOCK_ACQUIRE_LIMIT_REACHED_EXCEPTION,
687 new ExceptionFactoryImpl<exception::lock_acquire_limit_reached>());
688 register_exception(
689 LOCK_OWNERSHIP_LOST_EXCEPTION,
690 new ExceptionFactoryImpl<exception::lock_ownership_lost>());
691 register_exception(
692 CP_GROUP_DESTROYED_EXCEPTION,
693 new ExceptionFactoryImpl<exception::cp_group_destroyed>());
694 register_exception(CANNOT_REPLICATE_EXCEPTION,
695 new ExceptionFactoryImpl<exception::cannot_replicate>());
696 register_exception(LEADER_DEMOTED_EXCEPTION,
697 new ExceptionFactoryImpl<exception::leader_demoted>());
698 register_exception(
699 STALE_APPEND_REQUEST_EXCEPTION,
700 new ExceptionFactoryImpl<exception::stale_append_request>());
701 register_exception(NOT_LEADER_EXCEPTION,
702 new ExceptionFactoryImpl<exception::not_leader>());
703 register_exception(VERSION_MISMATCH_EXCEPTION,
704 new ExceptionFactoryImpl<exception::version_mismatch>());
705}
706
707ClientExceptionFactory::~ClientExceptionFactory()
708{
709 // release memory for the factories
710 for (std::unordered_map<
711 int,
712 hazelcast::client::protocol::ExceptionFactory*>::const_iterator it =
713 error_code_to_factory_.begin();
714 error_code_to_factory_.end() != it;
715 ++it) {
716 delete (it->second);
717 }
718}
719
720void
721ClientExceptionFactory::register_exception(int32_t error_code,
722 ExceptionFactory* factory)
723{
724 auto it = error_code_to_factory_.find(error_code);
725 if (error_code_to_factory_.end() != it) {
726 char msg[100];
727 util::hz_snprintf(
728 msg, 100, "Error code %d was already registered!!!", error_code);
729 BOOST_THROW_EXCEPTION(exception::illegal_state(
730 "ClientExceptionFactory::registerException", msg));
731 }
732
733 error_code_to_factory_[error_code] = factory;
734}
735
736std::exception_ptr
737ClientExceptionFactory::create_exception(
738 std::vector<codec::ErrorHolder>::const_iterator begin,
739 std::vector<codec::ErrorHolder>::const_iterator end) const
740{
741 if (begin == end) {
742 return nullptr;
743 }
744 auto factory = error_code_to_factory_.find(begin->error_code);
745 if (error_code_to_factory_.end() == factory) {
746 factory = error_code_to_factory_.find(
747 protocol::client_protocol_error_codes::UNDEFINED);
748 }
749 return factory->second->create_exception(*this,
750 begin->class_name,
751 begin->message.value_or("nullptr"),
752 begin->to_string(),
753 create_exception(begin + 1, end));
754}
755
756std::exception_ptr
757ClientExceptionFactory::create_exception(
758 const std::vector<codec::ErrorHolder>& errors) const
759{
760 return create_exception(errors.begin(), errors.end());
761}
762
763UsernamePasswordCredentials::UsernamePasswordCredentials(
764 const std::string& principal,
765 const std::string& password)
766 : name_(principal)
767 , password_(password)
768{}
769
770const std::string&
771UsernamePasswordCredentials::get_name() const
772{
773 return name_;
774}
775
776const std::string&
777UsernamePasswordCredentials::get_password() const
778{
779 return password_;
780}
781
782namespace codec {
783std::ostream&
784operator<<(std::ostream& out, const StackTraceElement& trace)
785{
786 return out << trace.file_name << " line " << trace.line_number << " :"
787 << trace.declaring_class << "." << trace.method_name;
788}
789
790std::vector<ErrorHolder>
791ErrorCodec::decode(ClientMessage& msg)
792{
793 // skip initial message frame
794 msg.skip_frame();
795
796 return msg.get<std::vector<ErrorHolder>>();
797}
798
799std::string
800ErrorHolder::to_string() const
801{
802 std::ostringstream out;
803 out << "Error code:" << error_code
804 << ", Class name that generated the error:" << class_name << ", ";
805 if (message) {
806 out << *message;
807 }
808 out << std::endl;
809 for (auto s : stack_trace) {
810 out << "\t" << s << std::endl;
811 }
812
813 return out.str();
814}
815
816namespace builtin {
817sql::sql_column_metadata
818custom_type_factory::create_sql_column_metadata(std::string name,
819 int32_t type,
820 bool is_nullable_exists,
821 bool nullability)
822{
823 using namespace hazelcast::client::sql;
824 if (type < static_cast<int32_t>(sql_column_type::varchar) ||
825 type > static_cast<int32_t>(sql_column_type::json)) {
826 throw hazelcast::client::exception::hazelcast_(
827 "custom_type_factory::create_sql_column_metadata",
828 (boost::format("Unexpected SQL column type = [%1%]") % type).str());
829 }
830
831 if (is_nullable_exists) {
832 return sql_column_metadata{
833 std::move(name), static_cast<sql_column_type>(type), nullability};
834 }
835
836 return sql_column_metadata{
837 std::move(name), static_cast<sql_column_type>(type), true};
838}
839
840std::shared_ptr<sql::sql_page>
841sql_page_codec::decode(ClientMessage& msg,
842 std::shared_ptr<sql::sql_row_metadata> row_metadata)
843{
844 // begin frame
845 msg.skip_frame();
846
847 bool last =
848 msg.peek(ClientMessage::SIZE_OF_FRAME_LENGTH_AND_FLAGS +
849 1)[ClientMessage::SIZE_OF_FRAME_LENGTH_AND_FLAGS] == 1;
850
851 msg.skip_frame();
852
853 auto column_type_ids = msg.get<std::vector<int32_t>>();
854
855 using column = std::vector<boost::any>;
856
857 using namespace sql;
858
859 auto number_of_columns = column_type_ids.size();
860 std::vector<column> columns(number_of_columns);
861 std::vector<sql_column_type> column_types(number_of_columns);
862
863 for (std::size_t i = 0; i < number_of_columns; ++i) {
864 auto column_type = static_cast<sql_column_type>(column_type_ids[i]);
865 column_types[i] = column_type;
866 columns[i] = sql_page_codec::decode_column_values(msg, column_type);
867 }
868
869 msg.fast_forward_to_end_frame();
870
871 auto page = std::make_shared<sql::sql_page>(
872 std::move(column_types), std::move(columns), last, row_metadata);
873 // se have to construct the rows properly
874 page->construct_rows();
875 return page;
876}
877std::vector<boost::any>
878sql_page_codec::decode_column_values(ClientMessage& msg,
879 sql::sql_column_type column_type)
880{
881 switch (column_type) {
882 case sql::sql_column_type::varchar:
883 return to_vector_of_any(
884 msg.get<std::vector<boost::optional<std::string>>>());
885 case sql::sql_column_type::boolean:
886 return to_vector_of_any(
887 builtin::list_cn_fixed_size_codec::decode<bool>(msg));
888 case sql::sql_column_type::tinyint:
889 return to_vector_of_any(
890 builtin::list_cn_fixed_size_codec::decode<byte>(msg));
891 case sql::sql_column_type::smallint:
892 return to_vector_of_any(
893 builtin::list_cn_fixed_size_codec::decode<int16_t>(msg));
894 case sql::sql_column_type::integer:
895 return to_vector_of_any(
896 builtin::list_cn_fixed_size_codec::decode<int32_t>(msg));
897 case sql::sql_column_type::bigint:
898 return to_vector_of_any(
899 builtin::list_cn_fixed_size_codec::decode<int64_t>(msg));
900 case sql::sql_column_type::real:
901 return to_vector_of_any(
902 builtin::list_cn_fixed_size_codec::decode<float>(msg));
903 case sql::sql_column_type::double_:
904 return to_vector_of_any(
905 builtin::list_cn_fixed_size_codec::decode<double>(msg));
906 case sql::sql_column_type::date:
907 return to_vector_of_any(
908 builtin::list_cn_fixed_size_codec::decode<local_date>(
909 msg));
910 case sql::sql_column_type::time:
911 return to_vector_of_any(
912 builtin::list_cn_fixed_size_codec::decode<local_time>(
913 msg));
914 case sql::sql_column_type::timestamp:
915 return to_vector_of_any(
916 builtin::list_cn_fixed_size_codec::decode<
917 local_date_time>(msg));
918 case sql::sql_column_type::timestamp_with_timezone:
919 return to_vector_of_any(
920 builtin::list_cn_fixed_size_codec::decode<
921 offset_date_time>(msg));
922 case sql::sql_column_type::decimal:
923 return to_vector_of_any(
924 builtin::list_cn_fixed_size_codec::decode<big_decimal>(
925 msg));
926 case sql::sql_column_type::null: {
927 msg.skip_frame_header_bytes();
928
929 auto size = msg.get<int32_t>();
930 return
931 std::vector<boost::any>(static_cast<size_t>(size));
932 }
933 case sql::sql_column_type::object:
934 return to_vector_of_any(
935 msg.get<std::vector<
936 boost::optional<serialization::pimpl::data>>>());
937 case sql::sql_column_type::json:
938 return to_vector_of_any(
939 msg.get<std::vector<boost::optional<hazelcast_json_value>>>());
940 default:
941 throw exception::illegal_state(
942 "ClientMessage::get<sql::sql_page>",
943 (boost::format("Unknown type %1%") %
944 static_cast<int32_t>(column_type))
945 .str());
946 }
947
948}
949
950} // namespace builtin
951} // namespace codec
952} // namespace protocol
953} // namespace client
954} // 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:...