From: Razvan Becheriu Date: Tue, 12 Mar 2019 15:02:37 +0000 (+0200) Subject: implemented getPage4 and getPage6 for Cassandra, sorting and filtering hosts in unitt... X-Git-Tag: Kea-1.6.0-beta~109 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b912c5a084037a414053de003526ae03db96e833;p=thirdparty%2Fkea.git implemented getPage4 and getPage6 for Cassandra, sorting and filtering hosts in unittests, implemented migration script for schema 4.0 --- diff --git a/configure.ac b/configure.ac index afc0947e86..7788322baf 100644 --- a/configure.ac +++ b/configure.ac @@ -1690,6 +1690,7 @@ AC_CONFIG_FILES([Makefile src/share/database/scripts/cql/Makefile src/share/database/scripts/cql/upgrade_1.0_to_2.0.sh src/share/database/scripts/cql/upgrade_2.0_to_3.0.sh + src/share/database/scripts/cql/upgrade_3.0_to_4.0.sh src/share/database/scripts/cql/wipe_data.sh src/share/database/scripts/mysql/Makefile src/share/database/scripts/mysql/upgrade_1.0_to_2.0.sh diff --git a/src/bin/admin/tests/cql_tests.sh.in b/src/bin/admin/tests/cql_tests.sh.in index 2ed76d39ec..44a6888753 100644 --- a/src/bin/admin/tests/cql_tests.sh.in +++ b/src/bin/admin/tests/cql_tests.sh.in @@ -85,7 +85,7 @@ cql_lease_version_test() { # Verify that kea-admin lease-version returns the correct version. version=$($keaadmin lease-version cql -u $db_user -p $db_password -n $db_name) - assert_str_eq "3.0" $version "Expected kea-admin to return %s, returned value was %s" + assert_str_eq "4.0" $version "Expected kea-admin to return %s, returned value was %s" # Wipe the database. cql_wipe @@ -150,17 +150,15 @@ cql_lease4_dump_test() { # 1433464245 corresponds to 2015-05-05 02:30:45 # 1436173267 corresponds to 2015-06-06 11:01:07 insert_cql="\ -INSERT INTO lease4(address, hwaddr, client_id, valid_lifetime, expire, subnet_id,\ - fqdn_fwd, fqdn_rev, hostname, state, user_context)\ - VALUES(-1073741302,textAsBlob('20'),textAsBlob('30'),40,1430694930,50,true,true,\ - 'one.example.com', 0, '');\ -INSERT INTO lease4(address, hwaddr, client_id, valid_lifetime, expire, subnet_id,\ - fqdn_fwd, fqdn_rev, hostname, state, user_context)\ - VALUES(-1073741301,NULL,textAsBlob('123'),40,1433464245,50,true,true,'', 1, '');\ -INSERT INTO lease4(address, hwaddr, client_id, valid_lifetime, expire, subnet_id,\ - fqdn_fwd, fqdn_rev, hostname, state, user_context)\ - VALUES(-1073741300,textAsBlob('22'),NULL,40,1436173267,50,true,true,\ - 'three.example.com', 2, '');" + INSERT INTO lease4 (address, hwaddr, client_id, valid_lifetime, expire, subnet_id, \ + fqdn_fwd, fqdn_rev, hostname, state, user_context) \ + VALUES (-1073741302,textAsBlob('20'),textAsBlob('30'),40,1430694930,50,true,true,'one.example.com', 0, '');\ + INSERT INTO lease4 (address, hwaddr, client_id, valid_lifetime, expire, subnet_id, \ + fqdn_fwd, fqdn_rev, hostname, state, user_context) \ + VALUES (-1073741301,NULL,textAsBlob('123'),40,1433464245,50,true,true,'', 1, '');\ + INSERT INTO lease4 (address, hwaddr, client_id, valid_lifetime, expire, subnet_id, \ + fqdn_fwd, fqdn_rev, hostname, state, user_context) \ + VALUES (-1073741300,textAsBlob('22'),NULL,40,1436173267,50,true,true,'three.example.com', 2, '');" cql_execute "$insert_cql" assert_eq 0 $? "insert into lease4 failed, expected exit code %d, actual %d" @@ -217,21 +215,21 @@ cql_lease6_dump_test() { # 1433464245 corresponds to 2015-05-05 02:30:45 # 1436173267 corresponds to 2015-06-06 11:01:07 insert_cql="\ -INSERT INTO lease6(address, duid, valid_lifetime, expire, subnet_id,\ - pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname,\ - hwaddr, hwtype, hwaddr_source, state, user_context)\ - VALUES('2001:db8::10',textAsBlob('20'),30,1430694930,40,50,1,60,70,true,true,\ - 'one.example.com',textAsBlob('80'),90,16,0,'');\ -INSERT INTO lease6(address, duid, valid_lifetime, expire, subnet_id,\ - pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname,\ - hwaddr, hwtype, hwaddr_source, state, user_context)\ - VALUES('2001:db8::11',NULL,30,1433464245,40,50,1,60,70,true,true,\ - '',textAsBlob('80'),90,1,1,'');\ -INSERT INTO lease6(address, duid, valid_lifetime, expire, subnet_id,\ - pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname,\ - hwaddr, hwtype, hwaddr_source, state, user_context)\ - VALUES('2001:db8::12',textAsBlob('21'),30,1436173267,40,50,1,60,70,true,true,\ - 'three.example.com',textAsBlob('80'),90,4,2,'');" + INSERT INTO lease6 (address, duid, valid_lifetime, expire, subnet_id, \ + pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, \ + hwaddr, hwtype, hwaddr_source, state, user_context) \ + VALUES ('2001:db8::10',textAsBlob('20'),30,1430694930,40,50,1,60,70,true,true, \ + 'one.example.com',textAsBlob('80'),90,16,0,'');\ + INSERT INTO lease6 (address, duid, valid_lifetime, expire, subnet_id, \ + pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, \ + hwaddr, hwtype, hwaddr_source, state, user_context) \ + VALUES ('2001:db8::11',NULL,30,1433464245,40,50,1,60,70,true,true, \ + '',textAsBlob('80'),90,1,1,'');\ + INSERT INTO lease6 (address, duid, valid_lifetime, expire, subnet_id, \ + pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, \ + hwaddr, hwtype, hwaddr_source, state, user_context) \ + VALUES ('2001:db8::12',textAsBlob('21'),30,1436173267,40,50,1,60,70,true,true, \ + 'three.example.com',textAsBlob('80'),90,4,2,'');" cql_execute "$insert_cql" assert_eq 0 $? "insert into lease6 failed, expected exit code %d, actual %d" @@ -260,7 +258,7 @@ cql_upgrade_schema_to_version() { # Check if the scripts directory exists at all. if [ ! -d ${db_scripts_dir}/cql ]; then - log_error "Invalid scripts directory: ${db_scripts_dir}/mysql" + log_error "Invalid scripts directory: ${db_scripts_dir}/cql" exit 1 fi @@ -306,17 +304,17 @@ cql_unused_subnet_id_test() { cql_upgrade_schema_to_version 2.0 # Now we need insert some hosts to "migrate" for both v4 and v6 - qry=\ -"insert into host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id)\ - values (1, 0, textAsBlob('0123456'), 0, 0, 0);\ - insert into host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id)\ - values (2, 0, textAsBlob('1123456'), 4, 0, 4);\ - insert into host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id)\ - values (3, 0, textAsBlob('2123456'), 0, 6, 6);\ - insert into host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id)\ - values (4, 0, textAsBlob('3123456'), 4, 6, 0);\ - insert into host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id)\ - values (5, 0, textAsBlob('3123456'), -1, 6, 6);" + qry="\ + INSERT INTO host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id) \ + VALUES (1, 0, textAsBlob('0123456'), 0, 0, 0);\ + INSERT INTO host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id) \ + VALUES (2, 0, textAsBlob('1123456'), 4, 0, 4);\ + INSERT INTO host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id) \ + VALUES (3, 0, textAsBlob('2123456'), 0, 6, 6);\ + INSERT INTO host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id) \ + VALUES (4, 0, textAsBlob('3123456'), 4, 6, 0);\ + INSERT INTO host_reservations (id, host_identifier_type, host_identifier, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id) \ + VALUES (5, 0, textAsBlob('3123456'), -1, 6, 6);" cql_execute "$qry" assert_eq 0 $? "insert hosts failed, expected exit code: %d, actual: %d" @@ -337,14 +335,14 @@ cql_unused_subnet_id_test() { # Fetch host_reservation data for comparison echo "Exporting host_reservation data to $export_file ..." - qry=\ -"select id, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id from\ - host_reservations where id in(1,2,3,4,5);" + qry="\ + SELECT id, host_ipv4_subnet_id, host_ipv6_subnet_id, option_subnet_id\ + FROM hosts WHERE id IN (1,2,3,4,5) ALLOW FILTERING;" - cql_execute "$qry" >$export_file + cql_execute "$qry" > $export_file assert_eq 0 $? "insert hosts failed, expected exit code: %d, actual: %d" # Compare the dump output to reference file, they should be identical. - cmp -s $export_file $ref_file + cmp -s $export_file $ref_file assert_eq 0 $? "export file does not match reference file, expected exit code %d, actual %d" # remove the output file. @@ -357,6 +355,98 @@ cql_unused_subnet_id_test() { test_finish 0 } +# Verifies that you can upgrade from an earlier version and +# that all hosts and options from old host_reseravation table (version 3.0) are +# converted to new schema (version 4.0) with new key partition key and are +# moved to new hosts table +cql_upgrade_hosts_test() { + test_start "cql.update_hosts_test" + + # Let's wipe the whole database + cql_wipe + + # We need to create an older database with lease data so we can + # verify the upgrade mechanisms which convert subnet id values + # + # Initialize database to schema 1.0. + cql_execute_script @abs_top_srcdir@/src/bin/admin/tests/dhcpdb_create_1.0.cql + + # Now upgrade to schema 3.0, the version just before global HRs + cql_upgrade_schema_to_version 3.0 + + # Now we need insert some hosts to "migrate" for both v4 and v6 + test_dir="@abs_top_srcdir@/src/bin/admin/tests" + data_file="$test_dir/data/cql.hosts_data_test.csv" + ref_file="$test_dir/data/cql.hosts_data_test.reference.csv" + + output_dir="@abs_top_builddir@/src/bin/admin/tests" + export_file="$output_dir/data/cql.hosts_test.csv" + sorted_file="$output_dir/data/cql.hosts_test.sorted.csv" + + # Fetch host_reservation data for comparison + echo "Exporting host_reservation data to $export_file ..." + + qry="\ + COPY host_reservations \ + (id, host_identifier, host_identifier_type, host_ipv4_subnet_id, \ + host_ipv6_subnet_id, host_ipv4_address, host_ipv4_next_server, \ + host_ipv4_server_hostname, host_ipv4_boot_file_name, hostname, \ + auth_key, user_context, host_ipv4_client_classes, \ + host_ipv6_client_classes, reserved_ipv6_prefix_address, \ + reserved_ipv6_prefix_length, reserved_ipv6_prefix_address_type, \ + iaid, option_universe, option_code, option_value, \ + option_formatted_value, option_space, option_is_persistent, \ + option_client_class, option_subnet_id, option_user_context, \ + option_scope_id) \ + FROM '$data_file'" + + cql_execute "$qry" + assert_eq 0 $? "insert hosts failed, expected exit code: %d, actual: %d" + + # Ok, we have a 3.0 database with hosts and options. Let's upgrade it. + ${keaadmin} lease-upgrade cql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir + ERRCODE=$? + + # Upgrade should succeed + assert_eq 0 $ERRCODE "upgrade failed" + + qry="\ + COPY hosts \ + (id, key, host_identifier, host_identifier_type, host_ipv4_subnet_id, \ + host_ipv6_subnet_id, host_ipv4_address, host_ipv4_next_server, \ + host_ipv4_server_hostname, host_ipv4_boot_file_name, hostname, \ + auth_key, user_context, host_ipv4_client_classes, \ + host_ipv6_client_classes, reserved_ipv6_prefix_address, \ + reserved_ipv6_prefix_length, reserved_ipv6_prefix_address_type, \ + iaid, option_universe, option_code, option_value, \ + option_formatted_value, option_space, option_is_persistent, \ + option_client_class, option_subnet_id, option_user_context, \ + option_scope_id) \ + TO '$export_file'" + + cql_execute "$qry" + assert_eq 0 $? "insert hosts failed, expected exit code: %d, actual: %d" + + # sort data so we can compare + cat $export_file | sort -V > $sorted_file + + # Compare the dump output to reference file, they should be identical. + cmp -s $sorted_file $ref_file + assert_eq 0 $? "export file does not match reference file, expected exit code %d, actual %d" + + # remove the output file. + rm $export_file + + # remove the sorted file. + rm $sorted_file + + # Wipe the database. + cql_wipe + + # Report test success. + test_finish 0 +} + # Run tests. cql_lease_init_test @@ -365,3 +455,4 @@ cql_upgrade_test cql_lease4_dump_test cql_lease6_dump_test cql_unused_subnet_id_test +cql_upgrade_hosts_test diff --git a/src/bin/admin/tests/data/cql.hosts_data_test.csv b/src/bin/admin/tests/data/cql.hosts_data_test.csv new file mode 100644 index 0000000000..1712f8c4b1 --- /dev/null +++ b/src/bin/admin/tests/data/cql.hosts_data_test.csv @@ -0,0 +1,24 @@ +1105657659805715115,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,17,0x,2495,dhcp6,False,,0,,3 +2129388898029710264,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,1,0x,312131,vendor-encapsulated-options,False,,0,,3 +2370585748436022247,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,67,0x,my-boot-file,dhcp4,True,,0,,3 +2459636980433777721,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,59,0x,my-boot-file,dhcp6,True,,0,{ \"comment\": \"a host reservation\" },3 +5403514763123047131,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,254,0x,192.0.2.3,dhcp4,False,,0,,3 +5501234819855171334,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,17,0x,2495,dhcp6,False,,0,,3 +5747907930644082856,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,1,0x,,isc2,True,,0,,3 +5955003068494074400,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,59,0x,my-boot-file,dhcp6,True,,0,,3 +6399013866147252670,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,32,0x,3600,dhcp6,False,,0,,3 +6783601303445960591,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,32,0x,3600,dhcp6,False,,0,,3 +7821756928114620236,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,23,0x,64,dhcp4,False,,0,,3 +8973539074684426388,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,1,0x,,isc,True,,0,,3 +9211831388923168274,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,2,0x,"10.0.0.5,10.0.0.3,10.0.3.4",isc,False,,0,,3 +-650687214220680074,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,1024,0x,2001:db8:1::1,dhcp6,False,,0,,3 +-1123502337428230752,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,254,0x,192.0.2.3,dhcp4,False,,0,,3 +-1210691761766369036,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,67,0x,my-boot-file,dhcp4,True,,0,{ \"comment\": \"a host reservation\" },3 +-3907456719587717375,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,2,0x,"10.0.0.5,10.0.0.3,10.0.3.4",isc,False,,0,,3 +-5169419091664697091,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,2,0x,"3000::1,3000::2,3000::3",isc2,False,,0,,3 +-6372549629773775261,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,1,0x,312131,vendor-encapsulated-options,False,,0,,3 +-6378104957663278797,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,1,0x,,isc,True,,0,,3 +-7724068518921719729,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,1024,0x,2001:db8:1::1,dhcp6,False,,0,,3 +-7804940982500935489,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,23,0x,64,dhcp4,False,,0,,3 +-8100784457292204371,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,1,0x,,isc2,True,,0,,3 +-8306770918748488616,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,2,0x,"3000::1,3000::2,3000::3",isc2,False,,0,,3 diff --git a/src/bin/admin/tests/data/cql.hosts_data_test.reference.csv b/src/bin/admin/tests/data/cql.hosts_data_test.reference.csv new file mode 100644 index 0000000000..046a3317d1 --- /dev/null +++ b/src/bin/admin/tests/data/cql.hosts_data_test.reference.csv @@ -0,0 +1,24 @@ +1105657659805715115,5367868710821401223,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,17,0x,2495,dhcp6,False,,0,,3 +2129388898029710264,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,1,0x,312131,vendor-encapsulated-options,False,,0,,3 +2370585748436022247,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,67,0x,my-boot-file,dhcp4,True,,0,,3 +2459636980433777721,5367868710821401223,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,59,0x,my-boot-file,dhcp6,True,,0,{ \"comment\": \"a host reservation\" },3 +5403514763123047131,4012104063077014549,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,254,0x,192.0.2.3,dhcp4,False,,0,,3 +5501234819855171334,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,17,0x,2495,dhcp6,False,,0,,3 +5747907930644082856,5367868710821401223,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,1,0x,,isc2,True,,0,,3 +5955003068494074400,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,59,0x,my-boot-file,dhcp6,True,,0,,3 +6399013866147252670,5367868710821401223,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,32,0x,3600,dhcp6,False,,0,,3 +6783601303445960591,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,32,0x,3600,dhcp6,False,,0,,3 +7821756928114620236,4012104063077014549,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,23,0x,64,dhcp4,False,,0,,3 +8973539074684426388,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,1,0x,,isc,True,,0,,3 +9211831388923168274,4012104063077014549,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,2,0x,"10.0.0.5,10.0.0.3,10.0.3.4",isc,False,,0,,3 +-650687214220680074,5367868710821401223,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,1024,0x,2001:db8:1::1,dhcp6,False,,0,,3 +-1123502337428230752,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,254,0x,192.0.2.3,dhcp4,False,,0,,3 +-1210691761766369036,4012104063077014549,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,67,0x,my-boot-file,dhcp4,True,,0,{ \"comment\": \"a host reservation\" },3 +-3907456719587717375,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,2,0x,"10.0.0.5,10.0.0.3,10.0.3.4",isc,False,,0,,3 +-5169419091664697091,5367868710821401223,0x4142434445464748494b,1,1,101,0,0,,,,,,,,2001:db8::1,128,0,0,1,2,0x,"3000::1,3000::2,3000::3",isc2,False,,0,,3 +-6372549629773775261,4012104063077014549,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,1,0x,312131,vendor-encapsulated-options,False,,0,,3 +-6378104957663278797,4012104063077014549,0x414243444547,0,1,101,-1073741307,0,,,,,,,,::,0,-1,-1,0,1,0x,,isc,True,,0,,3 +-7724068518921719729,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,1024,0x,2001:db8:1::1,dhcp6,False,,0,,3 +-7804940982500935489,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,0,23,0x,64,dhcp4,False,,0,,3 +-8100784457292204371,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,1,0x,,isc2,True,,0,,3 +-8306770918748488616,-4885955325122621964,0x414243444548,0,2,102,0,0,,,,,,,,2001:db8::1,128,0,0,1,2,0x,"3000::1,3000::2,3000::3",isc2,False,,0,,3 diff --git a/src/bin/admin/tests/data/cql.subnet_id_test.reference.csv b/src/bin/admin/tests/data/cql.subnet_id_test.reference.csv index 2d474bde9e..a593be5672 100644 --- a/src/bin/admin/tests/data/cql.subnet_id_test.reference.csv +++ b/src/bin/admin/tests/data/cql.subnet_id_test.reference.csv @@ -1,10 +1,10 @@ id | host_ipv4_subnet_id | host_ipv6_subnet_id | option_subnet_id ----+---------------------+---------------------+------------------ - 1 | -1 | -1 | -1 2 | 4 | -1 | 4 - 3 | -1 | 6 | 6 4 | 4 | 6 | -1 + 3 | -1 | 6 | 6 5 | -1 | 6 | 6 + 1 | -1 | -1 | -1 (5 rows) diff --git a/src/lib/cql/cql_connection.h b/src/lib/cql/cql_connection.h index cf92be9b6f..0a6bdc67ce 100644 --- a/src/lib/cql/cql_connection.h +++ b/src/lib/cql/cql_connection.h @@ -49,9 +49,9 @@ constexpr uint32_t CQL_DRIVER_VERSION_MAJOR = CASS_VERSION_MAJOR; constexpr uint32_t CQL_DRIVER_VERSION_MINOR = CASS_VERSION_MINOR; /// @} -/// Define CQL schema version: 3.0 +/// Define CQL schema version: 4.0 /// @{ -constexpr uint32_t CQL_SCHEMA_VERSION_MAJOR = 3u; +constexpr uint32_t CQL_SCHEMA_VERSION_MAJOR = 4u; constexpr uint32_t CQL_SCHEMA_VERSION_MINOR = 0u; /// @} diff --git a/src/lib/dhcpsrv/cql_host_data_source.cc b/src/lib/dhcpsrv/cql_host_data_source.cc index 7e5c974c7a..29663a535d 100644 --- a/src/lib/dhcpsrv/cql_host_data_source.cc +++ b/src/lib/dhcpsrv/cql_host_data_source.cc @@ -140,7 +140,7 @@ namespace isc { namespace dhcp { /// @brief Provides mechanisms for sending and retrieving data from the -/// host_reservations table. +/// hosts table. class CqlHostExchange : public virtual CqlExchange { public: /// @brief Constructor @@ -227,10 +227,25 @@ public: /// values which uniquely determine an entry in the table. Uses FNV-1a /// on 64 bits. /// - /// The primary key aggregates: host_ipv4_subnet_id, host_ipv6_subnet_id, + /// The primary key clustering column aggregates: host_dentifier, + /// host_identifier_type, host_ipv4_subnet_id, host_ipv6_subnet_id, /// host_ipv4_address, reserved_ipv6_prefix_address, /// reserved_ipv6_prefix_length, option_code, option_space. - cass_int64_t hashIntoId() const; + uint64_t hashIntoId() const; + + /// @brief Create unique key for storage in table key. + /// + /// The primary key partition key aggregates: host_dentifier, + /// host_identifier_type, host_ipv4_subnet_id, host_ipv6_subnet_id, + /// host_ipv4_address + uint64_t hashIntoKey() const; + + /// @brief Create unique key string for a host. + /// + /// The primary key partition key aggregates: host_dentifier, + /// host_identifier_type, host_ipv4_subnet_id, host_ipv6_subnet_id, + /// host_ipv4_address + std::string hostKey() const; /// @brief Copy received data into Host object /// @@ -257,26 +272,22 @@ public: /// database) const OptionWrapper retrieveOption() const; - /// @brief Statement tags definitions + /// @brief Statement tags /// @{ // Inserts all parameters belonging to any reservation from a single host. - static constexpr StatementTag INSERT_HOST = - "INSERT_HOST"; + static constexpr StatementTag INSERT_HOST = "INSERT_HOST"; - // Retrieves hosts informations, IPv6 reservations and both IPv4 and IPv6 - // options associated with the hosts. - static constexpr StatementTag GET_HOST = - "GET_HOST"; + // Retrieves hosts information, IPv6 reservations and both IPv4 and IPv6 + // options associated with it. + static constexpr StatementTag GET_HOST = "GET_HOST"; // Retrieves host information, IPv6 reservations and both IPv4 and IPv6 - // options associated with the host. - static constexpr StatementTag GET_HOST_BY_HOST_ID = - "GET_HOST_BY_HOST_ID"; + // options associated with it. + static constexpr StatementTag GET_HOST_BY_HOST_ID = "GET_HOST_BY_HOST_ID"; // Retrieves host information along with the IPv4 options associated // with it. - static constexpr StatementTag GET_HOST_BY_IPV4_ADDRESS = - "GET_HOST_BY_IPV4_ADDRESS"; + static constexpr StatementTag GET_HOST_BY_IPV4_ADDRESS = "GET_HOST_BY_IPV4_ADDRESS"; // Retrieves host information and IPv4 options using subnet identifier // and client's identifier (i.e. hardware address or DUID). @@ -284,7 +295,7 @@ public: "GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID"; // Retrieves host information; IPv6 reservations and IPv6 options - // associated with a host using subnet identifier and client's + // associated with it using subnet identifier and client's // identifier (i.e. hardware address or DUID). static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID = "GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID"; @@ -295,13 +306,12 @@ public: "GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS"; // Retrieves host information, IPv6 reservations and IPv6 options - // associated with a host using prefix and prefix length. This query - // returns host information for a single host. However, multiple rows - // are returned due to left joining IPv6 reservations and IPv6 options. - // The number of rows returned is multiplication of number of existing - // IPv6 reservations and IPv6 options. - static constexpr StatementTag GET_HOST_BY_IPV6_PREFIX = - "GET_HOST_BY_IPV6_PREFIX"; + // associated with it using prefix and prefix length. The query returns + // host information for a single host. However, multiple rows are returned + // due to left joining IPv6 reservations and IPv6 options. The number of + // rows returned is multiplication of number of existing IPv6 reservations + // and IPv6 options. + static constexpr StatementTag GET_HOST_BY_IPV6_PREFIX = "GET_HOST_BY_IPV6_PREFIX"; // Retrieves host information and IPv6 options for the host using subnet // identifier and IPv6 reservation. @@ -321,6 +331,47 @@ public: // associated with a host using subnet identifier. static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID = "GET_HOST_BY_IPV6_SUBNET_ID"; + + // Retrieves host information along with the IPv4 options associated + // with it using a subnet identifier from first host (paging). + static constexpr StatementTag GET_HOST_BY_IPV4_SUBNET_ID_LIMIT = + "GET_HOST_BY_IPV4_SUBNET_ID_LIMIT"; + + // Retrieves host information along with the IPv4 options associated + // with it using a subnet identifier from host (paging). + static constexpr StatementTag GET_HOST_BY_IPV4_SUBNET_ID_KEY = + "GET_HOST_BY_IPV4_SUBNET_ID_KEY"; + + // Retrieves host information along with the IPv4 options associated + // with it using a subnet identifier from next host (paging). + static constexpr StatementTag GET_HOST_BY_IPV4_SUBNET_ID_NEXT_KEY = + "GET_HOST_BY_IPV4_SUBNET_ID_NEXT_KEY"; + + // Retrieves host information along with the IPv4 options associated + // with it using a subnet identifier from host with a limit (paging). + static constexpr StatementTag GET_HOST_BY_IPV4_SUBNET_ID_PAGE = + "GET_HOST_BY_IPV4_SUBNET_ID_PAGE"; + + // Retrieves host information; IPv6 reservations and IPv6 options + // associated with it using subnet identifier from first host (paging). + static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID_LIMIT = + "GET_HOST_BY_IPV6_SUBNET_ID_LIMIT"; + + // Retrieves host information; IPv6 reservations and IPv6 options + // associated with it using subnet identifier from host (paging). + static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID_KEY = + "GET_HOST_BY_IPV6_SUBNET_ID_KEY"; + + // Retrieves host information; IPv6 reservations and IPv6 options + // associated with it using subnet identifier from next host (paging). + static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID_NEXT_KEY = + "GET_HOST_BY_IPV6_SUBNET_ID_NEXT_KEY"; + + // Retrieves host information; IPv6 reservations and IPv6 options + // associated with it using subnet identifier from host with a limit + // (paging). + static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID_PAGE = + "GET_HOST_BY_IPV6_SUBNET_ID_PAGE"; /// @} /// @brief Cassandra statements @@ -330,9 +381,14 @@ private: /// Pointer to Host object holding information being inserted into database. HostPtr host_; - /// @brief Primary key. Aggregates: host_identifier, host_identifier_type, - /// reserved_ipv6_prefix_address, reserved_ipv6_prefix_length, option_code, - /// option_space. + /// @brief Primary key. Partition key. Aggregates: host_dentifier, + /// host_identifier_type, host_ipv4_subnet_id host_ipv6_subnet_id, + /// host_ipv4_address + cass_int64_t key_; + + /// @brief Primary key. Clustering key. Aggregates: host_identifier, + /// host_identifier_type, reserved_ipv6_prefix_address, + /// reserved_ipv6_prefix_length, option_code, option_space. cass_int64_t id_; /// @brief Client's identifier (e.g. DUID, HW address) in binary format @@ -431,12 +487,21 @@ constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_PREFIX; constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS; constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID; constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID; +constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_LIMIT; +constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_LIMIT; +constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_NEXT_KEY; +constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_NEXT_KEY; +constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_KEY; +constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_KEY; +constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_PAGE; +constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_PAGE; constexpr StatementTag CqlHostExchange::DELETE_HOST; StatementMap CqlHostExchange::tagged_statements_ = { {INSERT_HOST, {INSERT_HOST, - "INSERT INTO host_reservations ( " + "INSERT INTO hosts ( " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -466,6 +531,8 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_user_context, " "option_scope_id " ") VALUES ( " + // key + "?, " // id "?, " // host @@ -479,6 +546,7 @@ StatementMap CqlHostExchange::tagged_statements_ = { {GET_HOST, {GET_HOST, "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -507,12 +575,13 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " + "FROM hosts " }}, {GET_HOST_BY_HOST_ID, {GET_HOST_BY_HOST_ID, "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -541,7 +610,7 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " + "FROM hosts " "WHERE host_identifier = ? " "AND host_identifier_type = ? " "ALLOW FILTERING " @@ -550,6 +619,7 @@ StatementMap CqlHostExchange::tagged_statements_ = { {GET_HOST_BY_IPV4_ADDRESS, {GET_HOST_BY_IPV4_ADDRESS, "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -578,7 +648,7 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " + "FROM hosts " "WHERE host_ipv4_address = ? " "ALLOW FILTERING " }}, @@ -586,6 +656,311 @@ StatementMap CqlHostExchange::tagged_statements_ = { {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID, {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID, "SELECT " + "key, " + "id, " + "host_identifier, " + "host_identifier_type, " + "host_ipv4_subnet_id, " + "host_ipv6_subnet_id, " + "host_ipv4_address, " + "host_ipv4_next_server, " + "host_ipv4_server_hostname, " + "host_ipv4_boot_file_name, " + "auth_key, " + "hostname, " + "user_context, " + "host_ipv4_client_classes, " + "host_ipv6_client_classes, " + "reserved_ipv6_prefix_address, " + "reserved_ipv6_prefix_length, " + "reserved_ipv6_prefix_address_type, " + "iaid, " + "option_universe, " + "option_code, " + "option_value, " + "option_formatted_value, " + "option_space, " + "option_is_persistent, " + "option_client_class, " + "option_subnet_id, " + "option_user_context, " + "option_scope_id " + "FROM hosts " + "WHERE host_ipv4_subnet_id = ? " + "AND host_identifier = ? " + "AND host_identifier_type = ? " + "ALLOW FILTERING " + }}, + + {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID, + {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID, + "SELECT " + "key, " + "id, " + "host_identifier, " + "host_identifier_type, " + "host_ipv4_subnet_id, " + "host_ipv6_subnet_id, " + "host_ipv4_address, " + "host_ipv4_next_server, " + "host_ipv4_server_hostname, " + "host_ipv4_boot_file_name, " + "auth_key, " + "hostname, " + "user_context, " + "host_ipv4_client_classes, " + "host_ipv6_client_classes, " + "reserved_ipv6_prefix_address, " + "reserved_ipv6_prefix_length, " + "reserved_ipv6_prefix_address_type, " + "iaid, " + "option_universe, " + "option_code, " + "option_value, " + "option_formatted_value, " + "option_space, " + "option_is_persistent, " + "option_client_class, " + "option_subnet_id, " + "option_user_context, " + "option_scope_id " + "FROM hosts " + "WHERE host_ipv6_subnet_id = ? " + "AND host_identifier = ? " + "AND host_identifier_type = ? " + "ALLOW FILTERING " + }}, + + {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS, + {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS, + "SELECT " + "key, " + "id, " + "host_identifier, " + "host_identifier_type, " + "host_ipv4_subnet_id, " + "host_ipv6_subnet_id, " + "host_ipv4_address, " + "host_ipv4_next_server, " + "host_ipv4_server_hostname, " + "host_ipv4_boot_file_name, " + "auth_key, " + "hostname, " + "user_context, " + "host_ipv4_client_classes, " + "host_ipv6_client_classes, " + "reserved_ipv6_prefix_address, " + "reserved_ipv6_prefix_length, " + "reserved_ipv6_prefix_address_type, " + "iaid, " + "option_universe, " + "option_code, " + "option_value, " + "option_formatted_value, " + "option_space, " + "option_is_persistent, " + "option_client_class, " + "option_subnet_id, " + "option_user_context, " + "option_scope_id " + "FROM hosts " + "WHERE host_ipv4_subnet_id = ? " + "AND host_ipv4_address = ? " + "ALLOW FILTERING " + }}, + + {GET_HOST_BY_IPV6_PREFIX, + {GET_HOST_BY_IPV6_PREFIX, + "SELECT " + "key, " + "id, " + "host_identifier, " + "host_identifier_type, " + "host_ipv4_subnet_id, " + "host_ipv6_subnet_id, " + "host_ipv4_address, " + "host_ipv4_next_server, " + "host_ipv4_server_hostname, " + "host_ipv4_boot_file_name, " + "auth_key, " + "hostname, " + "user_context, " + "host_ipv4_client_classes, " + "host_ipv6_client_classes, " + "reserved_ipv6_prefix_address, " + "reserved_ipv6_prefix_length, " + "reserved_ipv6_prefix_address_type, " + "iaid, " + "option_universe, " + "option_code, " + "option_value, " + "option_formatted_value, " + "option_space, " + "option_is_persistent, " + "option_client_class, " + "option_subnet_id, " + "option_user_context, " + "option_scope_id " + "FROM hosts " + "WHERE reserved_ipv6_prefix_address = ? " + "AND reserved_ipv6_prefix_length = ? " + "ALLOW FILTERING " + }}, + + {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS, + {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS, + "SELECT " + "key, " + "id, " + "host_identifier, " + "host_identifier_type, " + "host_ipv4_subnet_id, " + "host_ipv6_subnet_id, " + "host_ipv4_address, " + "host_ipv4_next_server, " + "host_ipv4_server_hostname, " + "host_ipv4_boot_file_name, " + "auth_key, " + "hostname, " + "user_context, " + "host_ipv4_client_classes, " + "host_ipv6_client_classes, " + "reserved_ipv6_prefix_address, " + "reserved_ipv6_prefix_length, " + "reserved_ipv6_prefix_address_type, " + "iaid, " + "option_universe, " + "option_code, " + "option_value, " + "option_formatted_value, " + "option_space, " + "option_is_persistent, " + "option_client_class, " + "option_subnet_id, " + "option_user_context, " + "option_scope_id " + "FROM hosts " + "WHERE host_ipv6_subnet_id = ? " + "AND reserved_ipv6_prefix_address = ? " + "ALLOW FILTERING " + }}, + + {GET_HOST_BY_IPV4_SUBNET_ID, + {GET_HOST_BY_IPV4_SUBNET_ID, + "SELECT " + "key, " + "id, " + "host_identifier, " + "host_identifier_type, " + "host_ipv4_subnet_id, " + "host_ipv6_subnet_id, " + "host_ipv4_address, " + "host_ipv4_next_server, " + "host_ipv4_server_hostname, " + "host_ipv4_boot_file_name, " + "auth_key, " + "hostname, " + "user_context, " + "host_ipv4_client_classes, " + "host_ipv6_client_classes, " + "reserved_ipv6_prefix_address, " + "reserved_ipv6_prefix_length, " + "reserved_ipv6_prefix_address_type, " + "iaid, " + "option_universe, " + "option_code, " + "option_value, " + "option_formatted_value, " + "option_space, " + "option_is_persistent, " + "option_client_class, " + "option_subnet_id, " + "option_user_context, " + "option_scope_id " + "FROM hosts " + "WHERE host_ipv4_subnet_id = ? " + "ALLOW FILTERING " + }}, + + {GET_HOST_BY_IPV6_SUBNET_ID, + {GET_HOST_BY_IPV6_SUBNET_ID, + "SELECT " + "key, " + "id, " + "host_identifier, " + "host_identifier_type, " + "host_ipv4_subnet_id, " + "host_ipv6_subnet_id, " + "host_ipv4_address, " + "host_ipv4_next_server, " + "host_ipv4_server_hostname, " + "host_ipv4_boot_file_name, " + "auth_key, " + "hostname, " + "user_context, " + "host_ipv4_client_classes, " + "host_ipv6_client_classes, " + "reserved_ipv6_prefix_address, " + "reserved_ipv6_prefix_length, " + "reserved_ipv6_prefix_address_type, " + "iaid, " + "option_universe, " + "option_code, " + "option_value, " + "option_formatted_value, " + "option_space, " + "option_is_persistent, " + "option_client_class, " + "option_subnet_id, " + "option_user_context, " + "option_scope_id " + "FROM hosts " + "WHERE host_ipv6_subnet_id = ? " + "ALLOW FILTERING " + }}, + + {GET_HOST_BY_IPV4_SUBNET_ID_LIMIT, + {GET_HOST_BY_IPV4_SUBNET_ID_LIMIT, + "SELECT " + "key, " + "id, " + "host_identifier, " + "host_identifier_type, " + "host_ipv4_subnet_id, " + "host_ipv6_subnet_id, " + "host_ipv4_address, " + "host_ipv4_next_server, " + "host_ipv4_server_hostname, " + "host_ipv4_boot_file_name, " + "auth_key, " + "hostname, " + "user_context, " + "host_ipv4_client_classes, " + "host_ipv6_client_classes, " + "reserved_ipv6_prefix_address, " + "reserved_ipv6_prefix_length, " + "reserved_ipv6_prefix_address_type, " + "iaid, " + "option_universe, " + "option_code, " + "option_value, " + "option_formatted_value, " + "option_space, " + "option_is_persistent, " + "option_client_class, " + "option_subnet_id, " + "option_user_context, " + "option_scope_id " + "FROM hosts " + "WHERE host_ipv4_subnet_id = ? " + "LIMIT 1 " + "ALLOW FILTERING " + }}, + + {GET_HOST_BY_IPV4_SUBNET_ID_NEXT_KEY, + {GET_HOST_BY_IPV4_SUBNET_ID_NEXT_KEY, + "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -614,16 +989,17 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " + "FROM hosts " "WHERE host_ipv4_subnet_id = ? " - "AND host_identifier = ? " - "AND host_identifier_type = ? " + "AND TOKEN(key) > TOKEN(?) " + "LIMIT 1 " "ALLOW FILTERING " }}, - {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID, - {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID, + {GET_HOST_BY_IPV4_SUBNET_ID_KEY, + {GET_HOST_BY_IPV4_SUBNET_ID_KEY, "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -652,16 +1028,15 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " - "WHERE host_ipv6_subnet_id = ? " - "AND host_identifier = ? " - "AND host_identifier_type = ? " + "FROM hosts " + "WHERE key = ? " "ALLOW FILTERING " }}, - {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS, - {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS, + {GET_HOST_BY_IPV4_SUBNET_ID_PAGE, + {GET_HOST_BY_IPV4_SUBNET_ID_PAGE, "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -690,15 +1065,17 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " + "FROM hosts " "WHERE host_ipv4_subnet_id = ? " - "AND host_ipv4_address = ? " + "AND id = ? " + "LIMIT 1 " "ALLOW FILTERING " }}, - {GET_HOST_BY_IPV6_PREFIX, - {GET_HOST_BY_IPV6_PREFIX, + {GET_HOST_BY_IPV6_SUBNET_ID_LIMIT, + {GET_HOST_BY_IPV6_SUBNET_ID_LIMIT, "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -727,15 +1104,16 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " - "WHERE reserved_ipv6_prefix_address = ? " - "AND reserved_ipv6_prefix_length = ? " + "FROM hosts " + "WHERE host_ipv6_subnet_id = ? " + "LIMIT 1 " "ALLOW FILTERING " }}, - {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS, - {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS, + {GET_HOST_BY_IPV6_SUBNET_ID_NEXT_KEY, + {GET_HOST_BY_IPV6_SUBNET_ID_NEXT_KEY, "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -764,15 +1142,17 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " + "FROM hosts " "WHERE host_ipv6_subnet_id = ? " - "AND reserved_ipv6_prefix_address = ? " + "AND TOKEN(key) > TOKEN(?) " + "LIMIT 1 " "ALLOW FILTERING " }}, - {GET_HOST_BY_IPV4_SUBNET_ID, - {GET_HOST_BY_IPV4_SUBNET_ID, + {GET_HOST_BY_IPV6_SUBNET_ID_KEY, + {GET_HOST_BY_IPV6_SUBNET_ID_KEY, "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -801,14 +1181,15 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " - "WHERE host_ipv4_subnet_id = ? " + "FROM hosts " + "WHERE key = ? " "ALLOW FILTERING " }}, - {GET_HOST_BY_IPV6_SUBNET_ID, - {GET_HOST_BY_IPV6_SUBNET_ID, + {GET_HOST_BY_IPV6_SUBNET_ID_PAGE, + {GET_HOST_BY_IPV6_SUBNET_ID_PAGE, "SELECT " + "key, " "id, " "host_identifier, " "host_identifier_type, " @@ -837,14 +1218,16 @@ StatementMap CqlHostExchange::tagged_statements_ = { "option_subnet_id, " "option_user_context, " "option_scope_id " - "FROM host_reservations " + "FROM hosts " "WHERE host_ipv6_subnet_id = ? " + "AND id = ? " + "LIMIT 1 " "ALLOW FILTERING " }}, {DELETE_HOST, {DELETE_HOST, - "DELETE FROM host_reservations WHERE id = ? " + "DELETE FROM hosts WHERE key = ? AND id = ? " "IF EXISTS " }} }; @@ -874,7 +1257,9 @@ CqlHostExchange::createBindForSelect(AnyArray& data, StatementTag /* not used */ // Start with a fresh array. data.clear(); - // id: blob + // key: bigint + data.add(&key_); + // id: bigint data.add(&id_); // host_identifier: blob data.add(&host_identifier_); @@ -1120,7 +1505,10 @@ CqlHostExchange::prepareExchange(const HostPtr& host, } // id: bigint - id_ = hashIntoId(); + id_ = static_cast(hashIntoId()); + + // key: bigint + key_ = static_cast(hashIntoKey()); } catch (const Exception& ex) { isc_throw(DbOperationError, "CqlHostExchange::prepareExchange(): " @@ -1143,6 +1531,7 @@ CqlHostExchange::createBindForMutation(const HostPtr& host, data.clear(); if (statement_tag == CqlHostExchange::INSERT_HOST) { + data.add(&key_); data.add(&id_); data.add(&host_identifier_); data.add(&host_identifier_type_); @@ -1199,6 +1588,7 @@ CqlHostExchange::createBindForDelete(const HostPtr& host, data.clear(); if (statement_tag == CqlHostExchange::DELETE_HOST) { + data.add(&key_); data.add(&id_); } @@ -1210,11 +1600,37 @@ CqlHostExchange::createBindForDelete(const HostPtr& host, } } -cass_int64_t +uint64_t CqlHostExchange::hashIntoId() const { // Add a separator between aggregated field to avoid collisions // between distinct entries. + // Get key. + std::stringstream key_stream; + key_stream << hostKey(); + key_stream << std::setw(V6ADDRESS_TEXT_MAX_LEN) << std::setfill('-') + << reserved_ipv6_prefix_address_; + key_stream << std::setw(4) << std::setfill('-') + << reserved_ipv6_prefix_length_; + key_stream << std::setw(4) << std::setfill('-') << option_code_; + key_stream << std::setw(OPTION_SPACE_MAX_LENGTH) << std::setfill('-') + << option_space_; + const std::string key = key_stream.str(); + + return (Hash64::hash(key)); +} + +uint64_t +CqlHostExchange::hashIntoKey() const { + const std::string key = hostKey(); + + return (Hash64::hash(key)); +} + +std::string +CqlHostExchange::hostKey() const { + // Add a separator between aggregated field to avoid collisions + // between distinct entries. // Get key. std::stringstream key_stream; if (host_ipv4_address_) { @@ -1230,18 +1646,7 @@ CqlHostExchange::hashIntoId() const { key_stream << std::setw(10) << std::setfill('-') << host_ipv6_subnet_id_; key_stream << std::setw(V4ADDRESS_TEXT_MAX_LEN) << std::setfill('-') << host_ipv4_address_; - key_stream << std::setw(V6ADDRESS_TEXT_MAX_LEN) << std::setfill('-') - << reserved_ipv6_prefix_address_; - key_stream << std::setw(4) << std::setfill('-') - << reserved_ipv6_prefix_length_; - key_stream << std::setw(4) << std::setfill('-') << option_code_; - key_stream << std::setw(OPTION_SPACE_MAX_LENGTH) << std::setfill('-') - << option_space_; - const std::string key = key_stream.str(); - - const cass_int64_t hash = static_cast(Hash64::hash(key)); - - return (hash); + return key_stream.str(); } boost::any @@ -1375,9 +1780,9 @@ CqlHostExchange::retrieveOption() const { if (!option_definition_ptr) { // If no definition found, we use generic option type. OptionBuffer option_buffer(option_value_.begin(), option_value_.end()); - option.reset(new Option(static_cast(option_universe_), - static_cast(option_code_), - option_buffer.begin(), option_buffer.end())); + option = boost::make_shared