37 #include <boost/algorithm/string/classification.hpp>
38 #include <boost/algorithm/string/split.hpp>
39 #include <boost/assert.hpp>
40 #include <boost/unordered_map.hpp>
55 typedef std::vector<uint8_t> HostIdentifier;
61 tuple<HostIdentifier, Host::IdentifierType, SubnetID, SubnetID, IOAddress> HostKey;
64 enum HostKeyComponent {
74 typedef std::unordered_map<HostKey, HostPtr, boost::hash<HostKey>> HostMap;
77 typedef std::pair<HostKey, HostPtr> HostPair;
80 struct OptionWrapper {
82 : option_descriptor_(option_descriptor), option_space_(option_space) {
85 std::string option_space_;
90 static constexpr
size_t CLIENT_CLASSES_MAX_LENGTH = 255u;
95 static constexpr
size_t HOSTNAME_MAX_LENGTH = 255u;
98 static constexpr
size_t OPTION_VALUE_MAX_LENGTH = 4096u;
101 static constexpr
size_t OPTION_FORMATTED_VALUE_MAX_LENGTH = 8192u;
104 static constexpr
size_t OPTION_SPACE_MAX_LENGTH = 128u;
109 static constexpr cass_int32_t MAX_IDENTIFIER_TYPE =
static_cast<cass_int32_t
>(Host::IDENT_FLEX);
113 static constexpr
char NULL_DHCP4_SERVER_HOSTNAME[] =
"";
114 static constexpr
char NULL_DHCP4_BOOT_FILE_NAME[] =
"";
115 static constexpr
char NULL_USER_CONTEXT[] =
"";
116 static constexpr
char NULL_RESERVED_IPV6_PREFIX_ADDRESS[] =
"::";
117 static constexpr cass_int32_t NULL_RESERVED_IPV6_PREFIX_LENGTH = 0;
118 static constexpr cass_int32_t NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE = -1;
119 static constexpr cass_int32_t NULL_IAID = -1;
120 static constexpr cass_int32_t NULL_OPTION_UNIVERSE = -1;
121 static constexpr cass_int32_t NULL_OPTION_CODE = -1;
123 static constexpr
char NULL_OPTION_FORMATTED_VALUE[] =
"";
124 static constexpr
char NULL_OPTION_SPACE[] =
"";
125 static constexpr cass_bool_t NULL_OPTION_IS_PERSISTENT = cass_false;
126 static constexpr
char NULL_OPTION_CLIENT_CLASS[] =
"";
127 static constexpr cass_int32_t NULL_OPTION_SUBNET_ID = -1;
128 static constexpr
char NULL_OPTION_USER_CONTEXT[] =
"";
129 static constexpr cass_int32_t NULL_OPTION_SCOPE_ID = -1;
134 static const IPv6Resrv NULL_IPV6_RESERVATION =
176 void prepareExchange(
const HostPtr& host,
179 const std::string& option_space,
195 void createBindForMutation(
const HostPtr& host,
198 const std::string& option_space,
216 void createBindForDelete(
const HostPtr& host,
219 const std::string& option_space,
233 cass_int64_t hashIntoId()
const;
242 virtual boost::any retrieve()
override;
250 const IPv6Resrv retrieveReservation()
const;
258 const OptionWrapper retrieveOption()
const;
274 "GET_HOST_BY_HOST_ID";
279 "GET_HOST_BY_IPV4_ADDRESS";
284 "GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID";
290 "GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID";
295 "GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS";
304 "GET_HOST_BY_IPV6_PREFIX";
309 "GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS";
333 cass_int32_t host_identifier_type_;
336 cass_int32_t host_ipv4_subnet_id_;
339 cass_int32_t host_ipv6_subnet_id_;
342 cass_int32_t host_ipv4_address_;
345 cass_int32_t host_ipv4_next_server_;
348 std::string host_ipv4_server_hostname_;
351 std::string host_ipv4_boot_file_name_;
354 std::string auth_key_;
357 std::string hostname_;
360 std::string user_context_;
363 std::string host_ipv4_client_classes_;
366 std::string host_ipv6_client_classes_;
369 std::string reserved_ipv6_prefix_address_;
372 cass_int32_t reserved_ipv6_prefix_length_;
376 cass_int32_t reserved_ipv6_prefix_address_type_;
383 cass_int32_t option_universe_;
386 cass_int32_t option_code_;
392 std::string option_formatted_value_;
395 std::string option_space_;
398 cass_bool_t option_is_persistent_;
401 std::string option_client_class_;
404 cass_int32_t option_subnet_id_;
407 std::string option_user_context_;
410 cass_int32_t option_scope_id_;
415 constexpr
StatementTag CqlHostExchange::GET_HOST_BY_HOST_ID;
416 constexpr
StatementTag CqlHostExchange::GET_HOST_BY_IPV4_ADDRESS;
417 constexpr
StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID;
418 constexpr
StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID;
419 constexpr
StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS;
420 constexpr
StatementTag CqlHostExchange::GET_HOST_BY_IPV6_PREFIX;
421 constexpr
StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS;
427 "INSERT INTO host_reservations ( "
430 "host_identifier_type, "
431 "host_ipv4_subnet_id, "
432 "host_ipv6_subnet_id, "
433 "host_ipv4_address, "
434 "host_ipv4_next_server, "
435 "host_ipv4_server_hostname, "
436 "host_ipv4_boot_file_name, "
440 "host_ipv4_client_classes, "
441 "host_ipv6_client_classes, "
442 "reserved_ipv6_prefix_address, "
443 "reserved_ipv6_prefix_length, "
444 "reserved_ipv6_prefix_address_type, "
449 "option_formatted_value, "
451 "option_is_persistent, "
452 "option_client_class, "
454 "option_user_context, "
460 "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
462 "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? "
472 "host_identifier_type, "
473 "host_ipv4_subnet_id, "
474 "host_ipv6_subnet_id, "
475 "host_ipv4_address, "
476 "host_ipv4_next_server, "
477 "host_ipv4_server_hostname, "
478 "host_ipv4_boot_file_name, "
482 "host_ipv4_client_classes, "
483 "host_ipv6_client_classes, "
484 "reserved_ipv6_prefix_address, "
485 "reserved_ipv6_prefix_length, "
486 "reserved_ipv6_prefix_address_type, "
491 "option_formatted_value, "
493 "option_is_persistent, "
494 "option_client_class, "
496 "option_user_context, "
498 "FROM host_reservations "
501 {GET_HOST_BY_HOST_ID,
502 {GET_HOST_BY_HOST_ID,
506 "host_identifier_type, "
507 "host_ipv4_subnet_id, "
508 "host_ipv6_subnet_id, "
509 "host_ipv4_address, "
510 "host_ipv4_next_server, "
511 "host_ipv4_server_hostname, "
512 "host_ipv4_boot_file_name, "
516 "host_ipv4_client_classes, "
517 "host_ipv6_client_classes, "
518 "reserved_ipv6_prefix_address, "
519 "reserved_ipv6_prefix_length, "
520 "reserved_ipv6_prefix_address_type, "
525 "option_formatted_value, "
527 "option_is_persistent, "
528 "option_client_class, "
530 "option_user_context, "
532 "FROM host_reservations "
533 "WHERE host_identifier = ? "
534 "AND host_identifier_type = ? "
538 {GET_HOST_BY_IPV4_ADDRESS,
539 {GET_HOST_BY_IPV4_ADDRESS,
543 "host_identifier_type, "
544 "host_ipv4_subnet_id, "
545 "host_ipv6_subnet_id, "
546 "host_ipv4_address, "
547 "host_ipv4_next_server, "
548 "host_ipv4_server_hostname, "
549 "host_ipv4_boot_file_name, "
553 "host_ipv4_client_classes, "
554 "host_ipv6_client_classes, "
555 "reserved_ipv6_prefix_address, "
556 "reserved_ipv6_prefix_length, "
557 "reserved_ipv6_prefix_address_type, "
562 "option_formatted_value, "
564 "option_is_persistent, "
565 "option_client_class, "
567 "option_user_context, "
569 "FROM host_reservations "
570 "WHERE host_ipv4_address = ? "
574 {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID,
575 {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID,
579 "host_identifier_type, "
580 "host_ipv4_subnet_id, "
581 "host_ipv6_subnet_id, "
582 "host_ipv4_address, "
583 "host_ipv4_next_server, "
584 "host_ipv4_server_hostname, "
585 "host_ipv4_boot_file_name, "
589 "host_ipv4_client_classes, "
590 "host_ipv6_client_classes, "
591 "reserved_ipv6_prefix_address, "
592 "reserved_ipv6_prefix_length, "
593 "reserved_ipv6_prefix_address_type, "
598 "option_formatted_value, "
600 "option_is_persistent, "
601 "option_client_class, "
603 "option_user_context, "
605 "FROM host_reservations "
606 "WHERE host_ipv4_subnet_id = ? "
607 "AND host_identifier = ? "
608 "AND host_identifier_type = ? "
612 {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID,
613 {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID,
617 "host_identifier_type, "
618 "host_ipv4_subnet_id, "
619 "host_ipv6_subnet_id, "
620 "host_ipv4_address, "
621 "host_ipv4_next_server, "
622 "host_ipv4_server_hostname, "
623 "host_ipv4_boot_file_name, "
627 "host_ipv4_client_classes, "
628 "host_ipv6_client_classes, "
629 "reserved_ipv6_prefix_address, "
630 "reserved_ipv6_prefix_length, "
631 "reserved_ipv6_prefix_address_type, "
636 "option_formatted_value, "
638 "option_is_persistent, "
639 "option_client_class, "
641 "option_user_context, "
643 "FROM host_reservations "
644 "WHERE host_ipv6_subnet_id = ? "
645 "AND host_identifier = ? "
646 "AND host_identifier_type = ? "
650 {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS,
651 {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS,
655 "host_identifier_type, "
656 "host_ipv4_subnet_id, "
657 "host_ipv6_subnet_id, "
658 "host_ipv4_address, "
659 "host_ipv4_next_server, "
660 "host_ipv4_server_hostname, "
661 "host_ipv4_boot_file_name, "
665 "host_ipv4_client_classes, "
666 "host_ipv6_client_classes, "
667 "reserved_ipv6_prefix_address, "
668 "reserved_ipv6_prefix_length, "
669 "reserved_ipv6_prefix_address_type, "
674 "option_formatted_value, "
676 "option_is_persistent, "
677 "option_client_class, "
679 "option_user_context, "
681 "FROM host_reservations "
682 "WHERE host_ipv4_subnet_id = ? "
683 "AND host_ipv4_address = ? "
687 {GET_HOST_BY_IPV6_PREFIX,
688 {GET_HOST_BY_IPV6_PREFIX,
692 "host_identifier_type, "
693 "host_ipv4_subnet_id, "
694 "host_ipv6_subnet_id, "
695 "host_ipv4_address, "
696 "host_ipv4_next_server, "
697 "host_ipv4_server_hostname, "
698 "host_ipv4_boot_file_name, "
702 "host_ipv4_client_classes, "
703 "host_ipv6_client_classes, "
704 "reserved_ipv6_prefix_address, "
705 "reserved_ipv6_prefix_length, "
706 "reserved_ipv6_prefix_address_type, "
711 "option_formatted_value, "
713 "option_is_persistent, "
714 "option_client_class, "
716 "option_user_context, "
718 "FROM host_reservations "
719 "WHERE reserved_ipv6_prefix_address = ? "
720 "AND reserved_ipv6_prefix_length = ? "
724 {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS,
725 {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS,
729 "host_identifier_type, "
730 "host_ipv4_subnet_id, "
731 "host_ipv6_subnet_id, "
732 "host_ipv4_address, "
733 "host_ipv4_next_server, "
734 "host_ipv4_server_hostname, "
735 "host_ipv4_boot_file_name, "
739 "host_ipv4_client_classes, "
740 "host_ipv6_client_classes, "
741 "reserved_ipv6_prefix_address, "
742 "reserved_ipv6_prefix_length, "
743 "reserved_ipv6_prefix_address_type, "
748 "option_formatted_value, "
750 "option_is_persistent, "
751 "option_client_class, "
753 "option_user_context, "
755 "FROM host_reservations "
756 "WHERE host_ipv6_subnet_id = ? "
757 "AND reserved_ipv6_prefix_address = ? "
763 "DELETE FROM host_reservations WHERE id = ? "
768 CqlHostExchange::CqlHostExchange()
769 : host_(NULL), id_(0), host_identifier_type_(0), host_ipv4_subnet_id_(0),
770 host_ipv6_subnet_id_(0), host_ipv4_address_(0), host_ipv4_next_server_(0),
771 host_ipv4_server_hostname_(NULL_DHCP4_SERVER_HOSTNAME),
772 host_ipv4_boot_file_name_(NULL_DHCP4_BOOT_FILE_NAME),
774 user_context_(NULL_USER_CONTEXT),
775 reserved_ipv6_prefix_length_(NULL_RESERVED_IPV6_PREFIX_LENGTH),
776 reserved_ipv6_prefix_address_type_(NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE),
777 iaid_(NULL_IAID), option_universe_(NULL_OPTION_UNIVERSE),
778 option_code_(NULL_OPTION_CODE),
779 option_is_persistent_(NULL_OPTION_IS_PERSISTENT),
780 option_subnet_id_(NULL_OPTION_SUBNET_ID),
781 option_user_context_(NULL_OPTION_USER_CONTEXT),
782 option_scope_id_(NULL_OPTION_SCOPE_ID) {
796 data.
add(&host_identifier_);
798 data.
add(&host_identifier_type_);
800 data.
add(&host_ipv4_subnet_id_);
802 data.
add(&host_ipv6_subnet_id_);
804 data.
add(&host_ipv4_address_);
806 data.
add(&host_ipv4_next_server_);
808 data.
add(&host_ipv4_server_hostname_);
810 data.
add(&host_ipv4_boot_file_name_);
812 data.
add(&auth_key_);
814 data.
add(&hostname_);
816 data.
add(&user_context_);
818 data.
add(&host_ipv4_client_classes_);
820 data.
add(&host_ipv6_client_classes_);
824 data.
add(&reserved_ipv6_prefix_address_);
826 data.
add(&reserved_ipv6_prefix_length_);
828 data.
add(&reserved_ipv6_prefix_address_type_);
835 data.
add(&option_universe_);
837 data.
add(&option_code_);
839 data.
add(&option_value_);
841 data.
add(&option_formatted_value_);
843 data.
add(&option_space_);
845 data.
add(&option_is_persistent_);
847 data.
add(&option_client_class_);
849 data.
add(&option_subnet_id_);
851 data.
add(&option_user_context_);
853 data.
add(&option_scope_id_);
861 const std::string& option_space,
873 HostIdentifier host_identifier = host->getIdentifier();
874 host_identifier_ =
CassBlob(host_identifier.begin(), host_identifier.end());
877 << host_identifier_.data() <<
" of length " << host_identifier_.size()
882 host_identifier_type_ =
static_cast<cass_int32_t
>(host->getIdentifierType());
883 if (host_identifier_type_ > MAX_IDENTIFIER_TYPE) {
885 "host identifier type returned: " << host_identifier_type_);
889 host_ipv4_subnet_id_ =
static_cast<cass_int32_t
>(host->getIPv4SubnetID());
892 host_ipv6_subnet_id_ =
static_cast<cass_int32_t
>(host->getIPv6SubnetID());
895 host_ipv4_address_ =
static_cast<cass_int32_t
>(host->getIPv4Reservation().toUint32());
898 host_ipv4_next_server_ =
static_cast<cass_int32_t
>(host->getNextServer().toUint32());
901 host_ipv4_server_hostname_ = host->getServerHostname();
904 host_ipv4_boot_file_name_ = host->getBootFileName();
907 auth_key_ = host->getKey().ToText();
910 hostname_ = host->getHostname();
911 if (hostname_.size() > HOSTNAME_MAX_LENGTH) {
913 << hostname_ <<
" of length " << hostname_.size()
914 <<
" is greater than allowed of " << HOSTNAME_MAX_LENGTH);
920 user_context_ = ctx->str();
922 user_context_ = NULL_USER_CONTEXT;
926 host_ipv4_client_classes_ = host->getClientClasses4().toText(
",");
927 if (host_ipv4_client_classes_.size() > CLIENT_CLASSES_MAX_LENGTH) {
929 "IPv4 client classes " << host_ipv4_client_classes_ <<
" of length "
930 << host_ipv4_client_classes_.size() <<
" is greater than allowed of "
931 << CLIENT_CLASSES_MAX_LENGTH);
935 host_ipv6_client_classes_ = host->getClientClasses6().toText(
",");
936 if (host_ipv6_client_classes_.size() > CLIENT_CLASSES_MAX_LENGTH) {
938 "IPv6 client classes " << host_ipv6_client_classes_ <<
" of length "
939 << host_ipv6_client_classes_.size() <<
" is greater than allowed of "
940 << CLIENT_CLASSES_MAX_LENGTH);
943 if (reservation == NULL) {
945 reserved_ipv6_prefix_address_ = NULL_RESERVED_IPV6_PREFIX_ADDRESS;
947 reserved_ipv6_prefix_length_ = NULL_RESERVED_IPV6_PREFIX_LENGTH;
949 reserved_ipv6_prefix_address_type_ = NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE;
956 reserved_ipv6_prefix_length_ =
static_cast<cass_int32_t
>(reservation->
getPrefixLen());
959 reserved_ipv6_prefix_address_type_ =
967 if (option_descriptor.
option_ == NULL) {
968 option_universe_ = NULL_OPTION_UNIVERSE;
969 option_code_ = NULL_OPTION_CODE;
970 option_value_ = NULL_OPTION_VALUE;
971 option_formatted_value_ = NULL_OPTION_FORMATTED_VALUE;
972 option_space_ = NULL_OPTION_SPACE;
973 option_is_persistent_ = NULL_OPTION_IS_PERSISTENT;
974 option_client_class_ = NULL_OPTION_CLIENT_CLASS;
975 option_subnet_id_ = NULL_OPTION_SUBNET_ID;
976 option_user_context_ = NULL_OPTION_USER_CONTEXT;
977 option_scope_id_ = NULL_OPTION_SCOPE_ID;
980 option_universe_ = option_descriptor.
option_->getUniverse();
983 option_code_ = option_descriptor.
option_->getType();
988 if (option_descriptor.
option_->len() >
989 option_descriptor.
option_->getHeaderLen()) {
995 option_descriptor.
option_->pack(buffer);
996 const char* buffer_ptr =
static_cast<const char*
>(buffer.
getData());
997 option_value_.assign(buffer_ptr + option_descriptor.
option_->getHeaderLen(),
1000 option_value_.clear();
1002 option_formatted_value_.clear();
1004 option_value_.clear();
1009 option_space_ = option_space;
1012 option_is_persistent_ = option_descriptor.
persistent_ ? cass_true : cass_false;
1016 option_client_class_.clear();
1020 option_subnet_id_ = subnet_id;
1022 option_subnet_id_ = 0;
1028 option_user_context_ = ctx->str();
1030 option_user_context_ = NULL_OPTION_USER_CONTEXT;
1035 option_scope_id_ = 3;
1042 "CqlHostExchange::prepareExchange(): "
1043 "could not copy data from host "
1044 << host->getHostname() <<
", reason: " << ex.
what());
1052 const std::string& option_space,
1055 prepareExchange(host, subnet_id, reservation, option_space, option_descriptor);
1063 data.
add(&host_identifier_);
1064 data.
add(&host_identifier_type_);
1065 data.
add(&host_ipv4_subnet_id_);
1066 data.
add(&host_ipv6_subnet_id_);
1067 data.
add(&host_ipv4_address_);
1068 data.
add(&host_ipv4_next_server_);
1069 data.
add(&host_ipv4_server_hostname_);
1070 data.
add(&host_ipv4_boot_file_name_);
1071 data.
add(&auth_key_);
1072 data.
add(&hostname_);
1073 data.
add(&user_context_);
1074 data.
add(&host_ipv4_client_classes_);
1075 data.
add(&host_ipv6_client_classes_);
1079 data.
add(&reserved_ipv6_prefix_address_);
1080 data.
add(&reserved_ipv6_prefix_length_);
1081 data.
add(&reserved_ipv6_prefix_address_type_);
1085 data.
add(&option_universe_);
1086 data.
add(&option_code_);
1087 data.
add(&option_value_);
1088 data.
add(&option_formatted_value_);
1089 data.
add(&option_space_);
1090 data.
add(&option_is_persistent_);
1091 data.
add(&option_client_class_);
1092 data.
add(&option_subnet_id_);
1093 data.
add(&option_user_context_);
1094 data.
add(&option_scope_id_);
1098 "CqlHostExchange::createBindForMutation(): "
1099 "could not create bind array from host "
1100 << host->getHostname() <<
", reason: " << ex.
what());
1108 const std::string& option_space,
1111 prepareExchange(host, subnet_id, reservation, option_space, option_descriptor);
1123 "CqlHostExchange::createBindForDelete(): "
1124 "could not create bind array from host "
1125 << host->getHostname() <<
", reason: " << ex.
what());
1135 std::stringstream key_stream;
1136 if (host_ipv4_address_) {
1139 key_stream << std::setw(10) << std::setfill(
'-') <<
"-";
1143 key_stream << std::setw(10) << std::setfill(
'-') << host_identifier_type_;
1145 key_stream << std::setw(10) << std::setfill(
'-') << host_ipv4_subnet_id_;
1146 key_stream << std::setw(10) << std::setfill(
'-') << host_ipv6_subnet_id_;
1147 key_stream << std::setw(V4ADDRESS_TEXT_MAX_LEN) << std::setfill(
'-')
1148 << host_ipv4_address_;
1149 key_stream << std::setw(V6ADDRESS_TEXT_MAX_LEN) << std::setfill(
'-')
1150 << reserved_ipv6_prefix_address_;
1151 key_stream << std::setw(4) << std::setfill(
'-')
1152 << reserved_ipv6_prefix_length_;
1153 key_stream << std::setw(4) << std::setfill(
'-') << option_code_;
1154 key_stream << std::setw(OPTION_SPACE_MAX_LENGTH) << std::setfill(
'-')
1156 const std::string key = key_stream.str();
1158 const cass_int64_t hash =
static_cast<cass_int64_t
>(Hash64::hash(key));
1165 const uint64_t
id =
static_cast<uint64_t
>(id_);
1167 HostIdentifier host_identifier =
1168 HostIdentifier(host_identifier_.begin(), host_identifier_.end());
1185 Host* host =
new Host(host_identifier.data(), host_identifier.size(),
1186 host_identifier_type, ipv4_subnet_id, ipv6_subnet_id,
1187 ipv4_reservation, hostname_,
1188 host_ipv4_client_classes_, host_ipv6_client_classes_,
1189 static_cast<uint32_t
>(host_ipv4_next_server_),
1190 host_ipv4_server_hostname_, host_ipv4_boot_file_name_,
1194 if (!user_context_.empty()) {
1197 if (!ctx || (ctx->getType() != Element::map)) {
1199 <<
"' is not a JSON map");
1204 <<
"' is invalid JSON: " << ex.
what());
1211 if (reservation != NULL_IPV6_RESERVATION &&
1217 if (option_wrapper.option_descriptor_) {
1218 if (option_wrapper.option_descriptor_->option_->getUniverse() ==
Option::V4) {
1219 host->
getCfgOption4()->add(*option_wrapper.option_descriptor_,
1220 option_wrapper.option_space_);
1221 }
else if (option_wrapper.option_descriptor_->option_->getUniverse() ==
Option::V6) {
1222 host->
getCfgOption6()->add(*option_wrapper.option_descriptor_,
1223 option_wrapper.option_space_);
1234 switch (reserved_ipv6_prefix_address_type_) {
1241 case NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE:
1242 return (NULL_IPV6_RESERVATION);
1245 "reservation type returned: " << reserved_ipv6_prefix_address_type_
1246 <<
". Only 0 (IA_NA) or 2 (IA_PD) are allowed.");
1250 reserved_ipv6_prefix_length_));
1264 if (option_space_.empty() || option_universe_ == NULL_OPTION_UNIVERSE) {
1276 if (vendor_id > 0) {
1285 if (!option_definition_ptr) {
1286 option_definition_ptr =
1291 if (!option_definition_ptr) {
1293 OptionBuffer option_buffer(option_value_.begin(), option_value_.end());
1295 static_cast<uint16_t
>(option_code_),
1296 option_buffer.begin(), option_buffer.end()));
1304 if (option_formatted_value_.empty()) {
1306 option_value_.end());
1307 option = option_definition_ptr->optionFactory(
1309 static_cast<uint16_t
>(option_code_), option_buffer.begin(),
1310 option_buffer.end());
1314 std::vector<std::string> split_vector;
1315 boost::split(split_vector, option_formatted_value_,
1316 boost::is_any_of(
","));
1317 option = option_definition_ptr->optionFactory(
1319 static_cast<uint16_t
>(option_code_), split_vector);
1324 option_formatted_value_)), option_space_);
1326 if (!option_user_context_.empty()) {
1329 if (!ctx || (ctx->getType() != Element::map)) {
1331 <<
"' is no a JSON map");
1333 result.option_descriptor_->setContext(ctx);
1336 <<
"' is invalid JSON: " << ex.
what());
1385 const uint8_t* identifier_begin,
1386 const size_t identifier_len)
const;
1395 const uint8_t prefix_len)
const;
1407 const uint8_t* identifier_begin,
1408 const size_t identifier_len)
const;
1428 const uint8_t* identifier_begin,
1429 const size_t identifier_len)
const;
1446 virtual std::string
getName()
const;
1464 const IPv6Resrv*
const reservation = NULL,
1465 const std::list<std::string>& option_spaces = std::list<std::string>(),
1485 const std::list<std::string>& option_spaces4,
1487 const std::list<std::string>& option_spaces6,
1533 const IPv6Resrv*
const reservation = NULL,
1534 const std::string& option_space = NULL_OPTION_SPACE,
1564 std::stringstream key_stream;
1565 HostIdentifier host_identifier = std::get<HOST_IDENTIFIER>(key);
1566 key_stream <<
DUID(host_identifier).
toText() <<
"-";
1567 key_stream << std::get<HOST_IDENTIFIER_TYPE>(key) <<
"-";
1568 key_stream << std::get<IPv4_SUBNET_ID>(key) <<
"-";
1569 key_stream << std::get<IPv6_SUBNET_ID>(key) <<
"-";
1570 key_stream << std::get<IPv4_RESERVATION>(key);
1571 const std::string key_string = key_stream.str();
1573 const uint64_t hash = Hash64::hash(key_string);
1575 return (
static_cast<std::size_t
>(hash));
1586 return (std::get<HOST_IDENTIFIER>(key1) == std::get<HOST_IDENTIFIER>(key2) &&
1587 std::get<HOST_IDENTIFIER_TYPE>(key1) ==
1588 std::get<HOST_IDENTIFIER_TYPE>(key2) &&
1589 std::get<IPv4_SUBNET_ID>(key1) == std::get<IPv4_SUBNET_ID>(key2) &&
1590 std::get<IPv6_SUBNET_ID>(key1) == std::get<IPv6_SUBNET_ID>(key2) &&
1591 std::get<IPv4_RESERVATION>(key1) == std::get<IPv4_RESERVATION>(key2));
1595 : dbconn_(parameters) {
1605 std::pair<uint32_t, uint32_t> db_version =
getVersion();
1606 if (code_version != db_version) {
1608 << code_version.first <<
"." << code_version.second
1609 <<
" found version: " << db_version.first <<
"."
1610 << db_version.second);
1634 std::list<std::string> option_spaces4 = cfg_option4->getOptionSpaceNames();
1635 std::list<std::string> vendor_spaces4 = cfg_option4->getVendorIdsSpaceNames();
1636 option_spaces4.insert(option_spaces4.end(), vendor_spaces4.begin(),
1637 vendor_spaces4.end());
1641 std::list<std::string> option_spaces6 = cfg_option6->getOptionSpaceNames();
1642 std::list<std::string> vendor_spaces6 = cfg_option6->getVendorIdsSpaceNames();
1643 option_spaces6.insert(option_spaces6.end(), vendor_spaces6.begin(),
1644 vendor_spaces6.end());
1651 if (std::distance(reservations.first, reservations.second) > 0) {
1652 for (
IPv6ResrvIterator it = reservations.first; result && it != reservations.second; ++it) {
1654 option_spaces6, cfg_option6);
1660 option_spaces6, cfg_option6);
1668 if (!address.
isV4()) {
1670 "address supplied is not an IPv4 address");
1674 cass_int32_t host_ipv4_subnet_id =
static_cast<cass_int32_t
>(subnet_id);
1675 cass_int32_t host_ipv4_address =
static_cast<cass_int32_t
>(address.
toUint32());
1679 where_values.
add(&host_ipv4_subnet_id);
1680 where_values.
add(&host_ipv4_address);
1692 const uint8_t* identifier_begin,
1693 const size_t identifier_len)
const {
1695 CassBlob host_identifier(identifier_begin, identifier_begin + identifier_len);
1696 cass_int32_t host_identifier_type =
static_cast<cass_int32_t
>(identifier_type);
1697 cass_int32_t host_ipv4_subnet_id =
static_cast<cass_int32_t
>(subnet_id);
1701 where_values.
add(&host_ipv4_subnet_id);
1702 where_values.
add(&host_identifier);
1703 where_values.
add(&host_identifier_type);
1714 const uint8_t prefix_len)
const {
1716 std::string reserved_ipv6_prefix_address = prefix.
toText();
1717 cass_int32_t reserved_ipv6_prefix_length = prefix_len;
1722 where_values.
add(&reserved_ipv6_prefix_address);
1723 where_values.
add(&reserved_ipv6_prefix_length);
1733 HostIdentifier host_identifier = host->getIdentifier();
1736 host_identifier.size());
1738 if (collection.empty()) {
1742 if (collection.size() >= 2u) {
1744 "CqlHostDataSource::get6(2): multiple records were "
1746 "database where only one was expected for statement "
1758 const uint8_t* identifier_begin,
1759 const size_t identifier_len)
const {
1761 cass_int32_t host_ipv6_subnet_id =
static_cast<cass_int32_t
>(subnet_id);
1762 CassBlob host_identifier(identifier_begin, identifier_begin + identifier_len);
1763 cass_int32_t host_identifier_type =
static_cast<cass_int32_t
>(identifier_type);
1767 where_values.
add(&host_ipv6_subnet_id);
1768 where_values.
add(&host_identifier);
1769 where_values.
add(&host_identifier_type);
1781 cass_int32_t host_ipv6_subnet_id =
static_cast<cass_int32_t
>(subnet_id);
1782 std::string reserved_ipv6_prefix_address = address.
toText();
1786 where_values.
add(&host_ipv6_subnet_id);
1787 where_values.
add(&reserved_ipv6_prefix_address);
1798 const uint8_t* identifier_begin,
1799 const size_t identifier_len)
const {
1801 CassBlob host_identifier(identifier_begin, identifier_begin + identifier_len);
1802 cass_int32_t host_identifier_type =
static_cast<cass_int32_t
>(identifier_type);
1806 where_values.
add(&host_identifier);
1807 where_values.
add(&host_identifier_type);
1819 cass_int32_t host_ipv4_address =
static_cast<cass_int32_t
>(address.
toUint32());
1823 where_values.
add(&host_ipv4_address);
1865 const std::list<std::string>& option_spaces,
1876 bool option_found =
false;
1877 for (
const std::string& space : option_spaces) {
1882 if (options && !options->empty()) {
1887 option_found =
true;
1894 if (result && !option_found) {
1906 const std::list<std::string>& option_spaces4,
1908 const std::list<std::string>& option_spaces6,
1919 if (result && cfg_option4 && !cfg_option4->empty()) {
1922 if (result && cfg_option6 && !cfg_option6->empty()) {
1926 (!cfg_option4 || cfg_option4->empty()) &&
1927 (!cfg_option6 || cfg_option6->empty())) {
1939 if (collection.empty()) {
1943 if (collection.size() >= 2u) {
1945 "found in the database where only one was expected for statement "
1949 return (*collection.begin());
1957 std::unique_ptr<CqlHostExchange> host_exchange(
new CqlHostExchange());
1959 statement_tag,
false);
1963 for (boost::any& host : collection) {
1964 host_collection.push_back(
HostPtr(boost::any_cast<Host*>(host)));
1971 for (
HostPtr& host : host_collection) {
1973 HostKey key = HostKey(host->getIdentifier(), host->getIdentifierType(),
1974 host->getIPv4SubnetID(), host->getIPv6SubnetID(),
1975 host->getIPv4Reservation());
1976 if (map.find(key) == map.end()) {
1984 for (HostPair pair : map) {
1985 result_collection.push_back(pair.second);
1987 return (result_collection);
1995 const std::string& option_space,
2004 std::unique_ptr<CqlHostExchange> host_exchange(
new CqlHostExchange());
2035 source_host->getIPv6Reservations();
2036 if (std::distance(reservations_range.first, reservations_range.second) > 0) {
2038 reservations_iterator != reservations_range.second;
2039 ++reservations_iterator) {
2040 if (!target_host->hasReservation(reservations_iterator->second)) {
2041 target_host->addReservation(reservations_iterator->second);
2047 source_host->getCfgOption4()->mergeTo(*target_host->getCfgOption4());
2050 source_host->getCfgOption6()->mergeTo(*target_host->getCfgOption6());
2070 HostPtr host = boost::const_pointer_cast<Host>(impl_->
get4(subnet_id, address));
2077 const uint8_t* identifier_begin,
const size_t identifier_len) {
2078 HostPtr host = boost::const_pointer_cast<Host>(impl_->
get4(subnet_id, identifier_type,
2079 identifier_begin, identifier_len));
2086 const uint8_t* identifier_begin,
const size_t identifier_len) {
2087 HostPtr host = boost::const_pointer_cast<Host>(impl_->
get6(subnet_id, identifier_type,
2088 identifier_begin, identifier_len));
2095 const uint8_t* identifier_begin,
2096 const size_t identifier_len)
const {
2099 return (impl_->
getAll(identifier_type, identifier_begin, identifier_len));
2106 return (impl_->
getAll4(address));
2112 const uint8_t* identifier_begin,
2113 const size_t identifier_len)
const {
2116 return (impl_->
get4(subnet_id, identifier_type, identifier_begin,
2125 return (impl_->
get4(subnet_id, address));
2131 const uint8_t* identifier_begin,
2132 const size_t identifier_len)
const {
2135 return (impl_->
get6(subnet_id, identifier_type, identifier_begin, identifier_len));
2140 const uint8_t prefix_len)
const {
2143 return (impl_->
get6(prefix, prefix_len));
2151 return (impl_->
get6(subnet_id, address));
2161 return std::string(
"cql");
2171 return std::string(
"Host data source that stores host information in the CQL database");