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