Kea 2.0.2
cql_lease_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2016-2021 Internet Systems Consortium, Inc. ("ISC")
2// Copyright (C) 2015-2018 Deutsche Telekom AG.
3//
4// Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
5// Andrei Pavel <andrei.pavel@qualitance.com>
6//
7// Licensed under the Apache License, Version 2.0 (the "License");
8// you may not use this file except in compliance with the License.
9// You may obtain a copy of the License at
10//
11// http://www.apache.org/licenses/LICENSE-2.0
12//
13// Unless required by applicable law or agreed to in writing, software
14// distributed under the License is distributed on an "AS IS" BASIS,
15// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16// See the License for the specific language governing permissions and
17// limitations under the License.
18
19#include <config.h>
20
23#include <dhcpsrv/dhcpsrv_log.h>
24
25#include <dhcp/duid.h>
26#include <dhcp/hwaddr.h>
27
28#include <asiolink/io_address.h>
29#include <boost/make_shared.hpp>
30
31using namespace isc::data;
32using namespace isc::db;
33using namespace isc::asiolink;
34
35namespace isc {
36namespace dhcp {
37
38static constexpr size_t HOSTNAME_MAX_LEN = 255u;
39static constexpr size_t ADDRESS6_TEXT_MAX_LEN = 39u;
40static constexpr char NULL_USER_CONTEXT[] = "";
41
49public:
50
55 : connection_(connection), valid_lifetime_(0), expire_(0),
56 current_expire_(0), subnet_id_(0), fqdn_fwd_(cass_false),
57 fqdn_rev_(cass_false), state_(0), user_context_(NULL_USER_CONTEXT) {
58 }
59
67 virtual void
68 createBindForSelect(AnyArray &data, StatementTag statement_tag = NULL) override = 0;
69
77 virtual boost::any retrieve() override = 0;
78
79protected:
80
83
86
88 cass_int64_t valid_lifetime_;
89
91 cass_int64_t expire_;
92
94 cass_int64_t current_expire_;
95
97 cass_int32_t subnet_id_;
98
100 cass_bool_t fqdn_fwd_;
101
103 cass_bool_t fqdn_rev_;
104
106 std::string hostname_;
107
109 cass_int32_t state_;
110
112 std::string user_context_;
113};
114
128public:
129
137 explicit CqlLease4Exchange(const CqlConnection &connection);
138
146 void createBindForInsert(const Lease4Ptr &lease, AnyArray &data);
147
156 void createBindForUpdate(const Lease4Ptr &lease, AnyArray &data,
157 StatementTag statement_tag = NULL);
158
167 void createBindForDelete(const Lease4Ptr &lease,
168 AnyArray &data,
169 StatementTag statement_tag = NULL);
170
177 virtual void
178 createBindForSelect(AnyArray &data, StatementTag statement_tag = NULL) override;
179
183 virtual boost::any retrieve() override;
184
190 void getLeaseCollection(StatementTag &statement_tag, AnyArray &data,
191 Lease4Collection &result);
192
198 void
199 getLease(StatementTag &statement_tag, AnyArray &data, Lease4Ptr &result);
200
208 void getExpiredLeases(const size_t &max_leases, Lease4Collection &expired_leases);
209
212
215 // Add entry to lease4 table
216 static constexpr StatementTag INSERT_LEASE4 = "INSERT_LEASE4";
217 // Update a Lease4 entry
218 static constexpr StatementTag UPDATE_LEASE4 = "UPDATE_LEASE4";
219 // Delete from lease4 by address
220 static constexpr StatementTag DELETE_LEASE4 = "DELETE_LEASE4";
221 // Delete expired lease4s in certain state
222 static constexpr StatementTag GET_LEASE4_EXPIRE = "GET_LEASE4_EXPIRE";
223 // Get lease4
224 static constexpr StatementTag GET_LEASE4 = "GET_LEASE4";
225 // Get lease4 by address
226 static constexpr StatementTag GET_LEASE4_ADDR = "GET_LEASE4_ADDR";
227 // Get lease4 by client ID
228 static constexpr StatementTag GET_LEASE4_CLIENTID = "GET_LEASE4_CLIENTID";
229 // Get lease4 by client ID & subnet ID
230 static constexpr StatementTag GET_LEASE4_CLIENTID_SUBID = "GET_LEASE4_CLIENTID_SUBID";
231 // Get lease4 by HW address
232 static constexpr StatementTag GET_LEASE4_HWADDR = "GET_LEASE4_HWADDR";
233 // Get lease4 by HW address & subnet ID
234 static constexpr StatementTag GET_LEASE4_HWADDR_SUBID = "GET_LEASE4_HWADDR_SUBID";
235 // Get range of lease4 from first lease with a limit
236 static constexpr StatementTag GET_LEASE4_LIMIT = "GET_LEASE4_LIMIT";
237 // Get range of lease4 from address with limit (paging)
238 static constexpr StatementTag GET_LEASE4_PAGE = "GET_LEASE4_PAGE";
239 // Get lease4 by subnet ID
240 static constexpr StatementTag GET_LEASE4_SUBID = "GET_LEASE4_SUBID";
241 // Get lease4 by hostname
242 static constexpr StatementTag GET_LEASE4_HOSTNAME = "GET_LEASE4_HOSTNAME";
244
245private:
246
247 // Pointer to lease object
248 Lease4Ptr lease_;
249 // IPv4 address
250 cass_int32_t address_;
251 // Client identification
252 CassBlob client_id_;
253}; // CqlLease4Exchange
254
269
271
272 // Inserts new IPv4 lease
273 {INSERT_LEASE4,
274 {INSERT_LEASE4,
275 "INSERT INTO lease4( "
276 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
277 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
278 ") VALUES ( "
279 "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? "
280 ") "
281 "IF NOT EXISTS "
282 }},
283
284 // Updates existing IPv4 lease
285 {UPDATE_LEASE4,
286 {UPDATE_LEASE4,
287 "UPDATE lease4 SET "
288 "hwaddr = ?, "
289 "client_id = ?, "
290 "subnet_id = ?, "
291 "valid_lifetime = ?, "
292 "expire = ?, "
293 "fqdn_fwd = ?, "
294 "fqdn_rev = ?, "
295 "hostname = ?, "
296 "state = ?, "
297 "user_context = ? "
298 "WHERE address = ? "
299 "IF expire = ? "
300 }},
301
302 // Deletes existing IPv4 lease
303 {DELETE_LEASE4,
304 {DELETE_LEASE4,
305 "DELETE FROM lease4 "
306 "WHERE address = ? "
307 "IF expire = ? "
308 }},
309
310 // Gets up to a certain number of expired IPv4 leases
311 {GET_LEASE4_EXPIRE,
312 {GET_LEASE4_EXPIRE,
313 "SELECT "
314 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
315 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
316 "FROM lease4 "
317 "WHERE state = ? "
318 "AND valid_lifetime < 4294967295 "
319 "AND expire < ? "
320 "LIMIT ? "
321 "ALLOW FILTERING "
322 }},
323
324 // Gets an IPv4 lease(s)
325 {GET_LEASE4,
326 {GET_LEASE4,
327 "SELECT "
328 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
329 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
330 "FROM lease4 "
331 }},
332
333 // Gets an IPv4 lease with specified IPv4 address
334 {GET_LEASE4_ADDR,
335 {GET_LEASE4_ADDR,
336 "SELECT "
337 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
338 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
339 "FROM lease4 "
340 "WHERE address = ? "
341 }},
342
343 // Gets an IPv4 lease(s) with specified client-id
344 {GET_LEASE4_CLIENTID,
345 {GET_LEASE4_CLIENTID,
346 "SELECT "
347 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
348 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
349 "FROM lease4 "
350 "WHERE client_id = ? "
351 "ALLOW FILTERING "
352 }},
353
354 // Gets an IPv4 lease with specified client-id and subnet-id
355 {GET_LEASE4_CLIENTID_SUBID,
356 {GET_LEASE4_CLIENTID_SUBID,
357 "SELECT "
358 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
359 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
360 "FROM lease4 "
361 "WHERE client_id = ? "
362 "AND subnet_id = ? "
363 "ALLOW FILTERING "
364 }},
365
366 // Gets all IPv4 leases with specified hardware address
367 {GET_LEASE4_HWADDR,
368 {GET_LEASE4_HWADDR,
369 "SELECT "
370 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
371 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
372 "FROM lease4 "
373 "WHERE hwaddr = ? "
374 "ALLOW FILTERING "
375 }},
376
377 // Gets an IPv4 lease with specified hardware addr and subnet-id
378 {GET_LEASE4_HWADDR_SUBID,
379 {GET_LEASE4_HWADDR_SUBID,
380 "SELECT "
381 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
382 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
383 "FROM lease4 "
384 "WHERE hwaddr = ? "
385 "AND subnet_id = ? "
386 "ALLOW FILTERING "
387 }},
388
389 // Get range of lease4 from first lease with a limit (paging)
390 {GET_LEASE4_LIMIT,
391 {GET_LEASE4_LIMIT,
392 "SELECT "
393 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
394 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
395 "FROM lease4 "
396 "LIMIT ? "
397 "ALLOW FILTERING "
398 }},
399
400 // Get range of lease4 from address with a limit (paging)
401 {GET_LEASE4_PAGE,
402 {GET_LEASE4_PAGE,
403 "SELECT "
404 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
405 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
406 "FROM lease4 "
407 "WHERE TOKEN(address) > TOKEN(?) "
408 "LIMIT ? "
409 "ALLOW FILTERING "
410 }},
411
412 // Gets an IPv4 lease(s) with specified subnet-id
413 {GET_LEASE4_SUBID,
414 {GET_LEASE4_SUBID,
415 "SELECT "
416 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
417 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
418 "FROM lease4 "
419 "WHERE subnet_id = ? "
420 "ALLOW FILTERING "}},
421
422 // Gets an IPv4 lease(s) with specified hostname
423 {GET_LEASE4_HOSTNAME,
424 {GET_LEASE4_HOSTNAME,
425 "SELECT "
426 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
427 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
428 "FROM lease4 "
429 "WHERE hostname = ? "
430 "ALLOW FILTERING "
431 }}
432};
433
435 : CqlLeaseExchange(connection), address_(0) {
436}
437
438void
440 if (!lease) {
441 isc_throw(BadValue, "CqlLease4Exchange::createBindForInsert(): "
442 "Lease4 object is NULL");
443 }
444 // Store lease object to ensure it remains valid.
445 lease_ = lease;
446 // Set up the structures for the various components of the lease4
447 // structure.
448
449 try {
450 // address: int
451 // The address in the Lease structure is an IOAddress object.
452 // Convert this to an integer for storage.
453 address_ = static_cast<cass_int32_t>(lease->addr_.toUint32());
454
455 // hwaddr: blob
456 if (lease_->hwaddr_ && lease_->hwaddr_->hwaddr_.size() > 0) {
457 if (lease_->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
459 "hardware address "
460 << lease_->hwaddr_->toText() << " of length "
461 << lease_->hwaddr_->hwaddr_.size()
462 << " exceeds maximum allowed length of "
464 }
465 hwaddr_ = lease_->hwaddr_->hwaddr_;
466 } else {
467 hwaddr_.clear();
468 }
469
470 // client_id: blob
471 if (lease_->client_id_ && lease_->client_id_->getClientId().size() > 0) {
472 client_id_ = lease_->client_id_->getClientId();
473 } else {
474 client_id_.clear();
475 }
476
477 // valid lifetime: bigint
478 valid_lifetime_ = static_cast<cass_int64_t>(lease_->valid_lft_);
479
480 // expire: bigint
481 // The lease structure holds the client last transmission time
483 // For convenience for external tools, this is converted to lease
484 // expiry time (expire). The relationship is given by:
485 // expire = cltt_ + valid_lft_
486 CqlExchange::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
487 expire_);
488
489 // subnet_id: int
490 subnet_id_ = static_cast<cass_int32_t>(lease_->subnet_id_);
491
492 // fqdn_fwd: boolean
493 fqdn_fwd_ = lease_->fqdn_fwd_ ? cass_true : cass_false;
494
495 // fqdn_rev: boolean
496 fqdn_rev_ = lease_->fqdn_rev_ ? cass_true : cass_false;
497
498 // hostname: varchar
499 if (lease_->hostname_.size() > HOSTNAME_MAX_LEN) {
501 "hostname " << lease_->hostname_ << " of length "
502 << lease_->hostname_.size()
503 << " exceeds maximum allowed length of "
504 << HOSTNAME_MAX_LEN);
505 }
506 hostname_ = lease_->hostname_;
507
508 // state: int
509 state_ = static_cast<cass_int32_t>(lease_->state_);
510
511 // user_context: text
512 ConstElementPtr ctx = lease_->getContext();
513 if (ctx) {
514 user_context_ = ctx->str();
515 } else {
516 user_context_ = NULL_USER_CONTEXT;
517 }
518
519 // Start with a fresh array.
520 data.clear();
521 data.add(&address_);
522 data.add(&hwaddr_);
523 data.add(&client_id_);
524 data.add(&valid_lifetime_);
525 data.add(&expire_);
526 data.add(&subnet_id_);
527 data.add(&fqdn_fwd_);
528 data.add(&fqdn_rev_);
529 data.add(&hostname_);
530 data.add(&state_);
531 data.add(&user_context_);
532
533 } catch (const Exception &ex) {
534 isc_throw(DbOperationError, "CqlLease4Exchange::createBindForInsert(): "
535 "could not create bind array from Lease4: " << lease_->addr_.toText()
536 << ", reason: " << ex.what());
537 }
538}
539
540void
542 StatementTag /* unused */) {
543 if (!lease) {
544 isc_throw(BadValue, "CqlLease4Exchange::createBindForUpdate(): "
545 "Lease4 object is NULL");
546 }
547 // Store lease object to ensure it remains valid.
548 lease_ = lease;
549 // Set up the structures for the various components of the lease4
550 // structure.
551
552 try {
553 // address: int
554 // The address in the Lease structure is an IOAddress object.
555 // Convert this to an integer for storage.
556 address_ = static_cast<cass_int32_t>(lease->addr_.toUint32());
557
558 // hwaddr: blob
559 if (lease_->hwaddr_ && lease_->hwaddr_->hwaddr_.size() > 0) {
560 if (lease_->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
562 "hardware address "
563 << lease_->hwaddr_->toText() << " of length "
564 << lease_->hwaddr_->hwaddr_.size()
565 << " exceeds maximum allowed length of "
567 }
568 hwaddr_ = lease_->hwaddr_->hwaddr_;
569 } else {
570 hwaddr_.clear();
571 }
572
573 // client_id: blob
574 if (lease_->client_id_ && lease_->client_id_->getClientId().size() > 0) {
575 client_id_ = lease_->client_id_->getClientId();
576 } else {
577 client_id_.clear();
578 }
579
580 // valid lifetime: bigint
581 valid_lifetime_ = static_cast<cass_int64_t>(lease_->valid_lft_);
582
583 // expire: bigint
584 // The lease structure holds the client last transmission time
586 // For convenience for external tools, this is converted to lease
587 // expiry time (expire). The relationship is given by:
588 // expire = cltt_ + valid_lft_
589 CqlExchange::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
590 expire_);
591
592 // subnet_id: int
593 subnet_id_ = static_cast<cass_int32_t>(lease_->subnet_id_);
594
595 // fqdn_fwd: boolean
596 fqdn_fwd_ = lease_->fqdn_fwd_ ? cass_true : cass_false;
597
598 // fqdn_rev: boolean
599 fqdn_rev_ = lease_->fqdn_rev_ ? cass_true : cass_false;
600
601 // hostname: varchar
602 if (lease_->hostname_.size() > HOSTNAME_MAX_LEN) {
604 "hostname " << lease_->hostname_ << " of length "
605 << lease_->hostname_.size()
606 << " exceeds maximum allowed length of "
607 << HOSTNAME_MAX_LEN);
608 }
609 hostname_ = lease_->hostname_;
610
611 // state: int
612 state_ = static_cast<cass_int32_t>(lease_->state_);
613
614 // user_context: text
615 ConstElementPtr ctx = lease_->getContext();
616 if (ctx) {
617 user_context_ = ctx->str();
618 } else {
619 user_context_ = NULL_USER_CONTEXT;
620 }
621
622 // Start with a fresh array.
623 data.clear();
624 data.add(&hwaddr_);
625 data.add(&client_id_);
626 data.add(&subnet_id_);
627 data.add(&valid_lifetime_);
628 data.add(&expire_);
629 data.add(&fqdn_fwd_);
630 data.add(&fqdn_rev_);
631 data.add(&hostname_);
632 data.add(&state_);
633 data.add(&user_context_);
634 data.add(&address_);
635
636 CqlExchange::convertToDatabaseTime(lease_->current_cltt_,
637 lease_->current_valid_lft_,
639 data.add(&current_expire_);
640 } catch (const Exception &ex) {
642 "CqlLease4Exchange::createBindUpdate(): "
643 "could not create bind array from Lease4: "
644 << lease_->addr_.toText() << ", reason: " << ex.what());
645 }
646}
647
648void
650 StatementTag /* unused */) {
651 if (!lease) {
652 isc_throw(BadValue, "CqlLease4Exchange::createBindForDelete(): "
653 "Lease4 object is NULL");
654 }
655 // Store lease object to ensure it remains valid.
656 lease_ = lease;
657
658 // Set up the structures for the various components of the lease4
659 // structure.
660 try {
661 // address: int
662 address_ = static_cast<cass_int32_t>(lease_->addr_.toUint32());
663
664 // Start with a fresh array.
665 data.clear();
666 data.add(&address_);
667
668 CqlExchange::convertToDatabaseTime(lease_->current_cltt_,
669 lease_->current_valid_lft_,
671 data.add(&current_expire_);
672 } catch (const Exception &ex) {
674 "CqlLease4Exchange::createBindForDelete(): "
675 "could not create bind array from Lease4: "
676 << lease_->addr_.toText() << ", reason: " << ex.what());
677 }
678}
679
680void
682 // Start with a fresh array.
683 data.clear();
684
685 // address: blob
686 data.add(&address_);
687
688 // hwaddr: blob
689 data.add(&hwaddr_);
690
691 // client_id: blob
692 data.add(&client_id_);
693
694 // valid_lifetime: bigint
695 data.add(&valid_lifetime_);
696
697 // expire: bigint
698 data.add(&expire_);
699
700 // subnet_id: int
701 data.add(&subnet_id_);
702
703 // fqdn_fwd: boolean
704 data.add(&fqdn_fwd_);
705
706 // fqdn_rev: boolean
707 data.add(&fqdn_rev_);
708
709 // hostname: varchar
710 data.add(&hostname_);
711
712 // state: int
713 data.add(&state_);
714
715 // user_context: text
716 data.add(&user_context_);
717}
718
719boost::any
721 try {
722 // Sanity checks
723 if (hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
725 "hardware address "
726 << HWAddr(hwaddr_, HTYPE_ETHER).toText()
727 << " of length " << hwaddr_.size()
728 << " exceeds maximum allowed length of "
730 }
731 if (client_id_.size() > ClientId::MAX_CLIENT_ID_LEN) {
733 "client ID " << ClientId(client_id_).toText()
734 << " of length " << client_id_.size()
735 << " exceeds maximum allowed length of "
737 }
738 if (hostname_.size() > HOSTNAME_MAX_LEN) {
740 "hostname" << hostname_ << " of length "
741 << hostname_.size()
742 << " exceeds maximum allowed length of "
743 << HOSTNAME_MAX_LEN);
744 }
745
746 time_t cltt = 0;
748
749 HWAddrPtr hwaddr = boost::make_shared<HWAddr>(hwaddr_, HTYPE_ETHER);
750
751 uint32_t addr4 = static_cast<uint32_t>(address_);
752
753 ConstElementPtr ctx;
754 if (!user_context_.empty()) {
755 ctx = Element::fromJSON(user_context_);
756 if (!ctx || (ctx->getType() != Element::map)) {
757 isc_throw(BadValue, "user context '" << user_context_
758 << "' is not a JSON map");
759 }
760 }
761
762 Lease4Ptr result(boost::make_shared<Lease4>(addr4, hwaddr, client_id_.data(),
763 client_id_.size(), valid_lifetime_,
765 hostname_));
766
767 result->state_ = state_;
768
769 if (ctx) {
770 result->setContext(ctx);
771 }
772
773 return (result);
774 } catch (const Exception &ex) {
776 "CqlLease4Exchange::retrieve(): "
777 "could not convert data to Lease4, reason: "
778 << ex.what());
779 }
780}
781
782void
784 Lease4Collection &result) {
785 AnyArray collection = executeSelect(connection_, data, statement_tag);
786
787 // Transfer Lease4 objects to result.
788 for (boost::any &element : collection) {
789 result.push_back(boost::any_cast<Lease4Ptr>(element));
790 }
791}
792
793void
795 Lease4Ptr &result) {
796 // This particular method is called when only one or zero matches is
797 // expected.
798 Lease4Collection collection;
799 getLeaseCollection(statement_tag, data, collection);
800
801 // Return single record if present, else clear the lease.
802 const size_t collection_size = collection.size();
803 if (collection_size >= 2u) {
805 "CqlLease4Exchange::getLease(): multiple records were found in "
806 "the database where only one was expected for statement "
807 << statement_tag);
808 } else if (collection_size == 0u) {
809 result.reset();
810 } else {
811 result = *collection.begin();
812 }
813}
814
815void
816CqlLease4Exchange::getExpiredLeases(const size_t &max_leases,
817 Lease4Collection &expired_leases) {
818 // Set up the WHERE clause value
819 cass_int32_t keep_state = Lease::STATE_EXPIRED_RECLAIMED;
820 cass_int64_t timestamp = static_cast<cass_int64_t>(time(NULL));
821
822 // If the number of leases is 0, we will return all leases. This is
823 // achieved by setting the limit to a very high value.
824 cass_int32_t limit = max_leases > 0u ? static_cast<cass_int32_t>(max_leases) :
825 std::numeric_limits<cass_int32_t>::max();
826
827 for (cass_int32_t state = Lease::STATE_DEFAULT;
828 state <= Lease::STATE_EXPIRED_RECLAIMED; ++state) {
829 if (state == keep_state) {
830 continue;
831 }
832
833 AnyArray data;
834 data.add(&state);
835 data.add(&timestamp);
836 data.add(&limit);
837
838 // Retrieve leases from the database.
839 Lease4Collection temp_collection;
841 temp_collection);
842
843 for (Lease4Ptr &lease : temp_collection) {
844 expired_leases.push_back(lease);
845 }
846 }
847}
848
862public:
863
871 explicit CqlLease6Exchange(const CqlConnection &connection);
872
880 void createBindForInsert(const Lease6Ptr &lease, AnyArray &data);
881
890 void createBindForUpdate(const Lease6Ptr &lease, AnyArray &data,
891 StatementTag statement_tag = NULL);
892
901 void createBindForDelete(const Lease6Ptr &lease,
902 AnyArray &data,
903 StatementTag statement_tag = NULL);
904
911 virtual void
912 createBindForSelect(AnyArray &data, StatementTag statement_tag = NULL) override;
913
917 virtual boost::any retrieve() override;
918
924 void getLeaseCollection(StatementTag &statement_tag, AnyArray &data,
925 Lease6Collection &result);
926
932 void
933 getLease(StatementTag &statement_tag, AnyArray &data, Lease6Ptr &result);
934
942 void getExpiredLeases(const size_t &max_leases, Lease6Collection &expired_leases);
943
946
949 static constexpr StatementTag INSERT_LEASE6 = "INSERT_LEASE6";
950 static constexpr StatementTag UPDATE_LEASE6 = "UPDATE_LEASE6";
951 static constexpr StatementTag DELETE_LEASE6 = "DELETE_LEASE6";
952 static constexpr StatementTag GET_LEASE6_EXPIRE = "GET_LEASE6_EXPIRE";
953 static constexpr StatementTag GET_LEASE6_ADDR = "GET_LEASE6_ADDR";
954 static constexpr StatementTag GET_LEASE6_DUID = "GET_LEASE6_DUID";
955 static constexpr StatementTag GET_LEASE6_DUID_IAID = "GET_LEASE6_DUID_IAID";
956 static constexpr StatementTag GET_LEASE6_DUID_IAID_SUBID = "GET_LEASE6_DUID_IAID_SUBID";
957 static constexpr StatementTag GET_LEASE6_LIMIT = "GET_LEASE6_LIMIT";
958 static constexpr StatementTag GET_LEASE6_PAGE = "GET_LEASE6_PAGE";
959 static constexpr StatementTag GET_LEASE6_HOSTNAME = "GET_LEASE6_HOSTNAME";
960 // @}
961
962private:
963
965 Lease6Ptr lease_;
966
968 std::string address_;
969
971 cass_int64_t pref_lifetime_;
972
974 CassBlob duid_;
975
977 cass_int32_t iaid_;
978
980 cass_int32_t lease_type_;
981
983 cass_int32_t prefix_len_;
984
986 cass_int32_t hwtype_;
987
989 cass_int32_t hwaddr_source_;
990}; // CqlLease6Exchange
991
1003
1005
1006 // Inserts new IPv6 lease
1007 {INSERT_LEASE6,
1008 {INSERT_LEASE6,
1009 "INSERT INTO lease6("
1010 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1011 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1012 "hwaddr_source, state, user_context "
1013 ") VALUES ("
1014 "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"
1015 ") "
1016 "IF NOT EXISTS "
1017 }},
1018
1019 // Updates existing IPv6 lease
1020 {UPDATE_LEASE6,
1021 {UPDATE_LEASE6,
1022 "UPDATE lease6 SET "
1023 "valid_lifetime = ?, "
1024 "expire = ?, "
1025 "pref_lifetime = ?, "
1026 "duid = ?, "
1027 "iaid = ?, "
1028 "subnet_id = ?, "
1029 "lease_type = ?, "
1030 "prefix_len = ?, "
1031 "fqdn_fwd = ?, "
1032 "fqdn_rev = ?, "
1033 "hostname = ?, "
1034 "hwaddr = ?, "
1035 "hwtype = ?, "
1036 "hwaddr_source = ?, "
1037 "state = ?, "
1038 "user_context = ? "
1039 "WHERE address = ? "
1040 "IF expire = ? "
1041 }},
1042
1043 // Deletes existing IPv6 lease
1044 {DELETE_LEASE6,
1045 {DELETE_LEASE6,
1046 "DELETE FROM lease6 "
1047 "WHERE address = ? "
1048 "IF expire = ? "
1049 }},
1050
1051 // Gets up to a certain number of expired IPv6 leases
1052 {GET_LEASE6_EXPIRE,
1053 {GET_LEASE6_EXPIRE,
1054 "SELECT "
1055 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1056 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1057 "hwaddr_source, state, user_context "
1058 "FROM lease6 "
1059 "WHERE state = ? "
1060 "AND valid_lifetime < 4294967295 "
1061 "AND expire < ? "
1062 "LIMIT ? "
1063 "ALLOW FILTERING "
1064 }},
1065
1066 // Gets an IPv6 lease with specified IPv6 address
1067 {GET_LEASE6_ADDR,
1068 {GET_LEASE6_ADDR,
1069 "SELECT "
1070 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1071 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1072 "hwaddr_source, state, user_context "
1073 "FROM lease6 "
1074 "WHERE address = ? "
1075 "AND lease_type = ? "
1076 "ALLOW FILTERING "
1077 }},
1078
1079 // Gets an IPv6 lease with specified duid
1080 {GET_LEASE6_DUID,
1081 {GET_LEASE6_DUID,
1082 "SELECT "
1083 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1084 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1085 "hwaddr_source, state, user_context "
1086 "FROM lease6 "
1087 "WHERE duid = ? "
1088 "ALLOW FILTERING "
1089 }},
1090
1091 // Gets an IPv6 lease(s) with specified duid and iaid
1092 {GET_LEASE6_DUID_IAID,
1093 {GET_LEASE6_DUID_IAID,
1094 "SELECT "
1095 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1096 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1097 "hwaddr_source, state, user_context "
1098 "FROM lease6 "
1099 "WHERE duid = ? AND iaid = ? "
1100 "AND lease_type = ? "
1101 "ALLOW FILTERING "
1102 }},
1103
1104 // Gets an IPv6 lease with specified duid, iaid and subnet-id
1105 {GET_LEASE6_DUID_IAID_SUBID,
1106 {GET_LEASE6_DUID_IAID_SUBID,
1107 "SELECT "
1108 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1109 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1110 "hwaddr_source, state, user_context "
1111 "FROM lease6 "
1112 "WHERE duid = ? AND iaid = ? "
1113 "AND lease_type = ? "
1114 "AND subnet_id = ? "
1115 "ALLOW FILTERING "
1116 }},
1117
1118 // Get range of IPv6 leases from first lease with a limit (paging)
1119 {GET_LEASE6_LIMIT,
1120 {GET_LEASE6_LIMIT,
1121 "SELECT "
1122 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1123 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1124 "hwaddr_source, state, user_context "
1125 "FROM lease6 "
1126 "LIMIT ? "
1127 "ALLOW FILTERING "
1128 }},
1129
1130 // Get range of IPv6 leases from address with a limit (paging)
1131 {GET_LEASE6_PAGE,
1132 {GET_LEASE6_PAGE,
1133 "SELECT "
1134 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1135 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1136 "hwaddr_source, state, user_context "
1137 "FROM lease6 "
1138 "WHERE TOKEN(address) > TOKEN(?) "
1139 "LIMIT ? "
1140 "ALLOW FILTERING "
1141 }},
1142
1143 // Gets an IPv6 lease(s) with specified hostname
1144 {GET_LEASE6_HOSTNAME,
1145 {GET_LEASE6_HOSTNAME,
1146 "SELECT "
1147 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1148 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1149 "hwaddr_source, state, user_context "
1150 "FROM lease6 "
1151 "WHERE hostname = ? "
1152 "ALLOW FILTERING "
1153 }}
1154};
1155
1157 : CqlLeaseExchange(connection), pref_lifetime_(0), iaid_(0), lease_type_(0),
1158 prefix_len_(0), hwtype_(0), hwaddr_source_(0) {
1159}
1160
1161void
1163 if (!lease) {
1164 isc_throw(BadValue, "CqlLease6Exchange::createBindForInsert(): "
1165 "Lease6 object is NULL");
1166 }
1167 // Store lease object to ensure it remains valid.
1168 lease_ = lease;
1169
1170 // Set up the structures for the various components of the lease4
1171 // structure.
1172 try {
1173 // address: varchar
1174 address_ = lease_->addr_.toText();
1175 if (address_.size() > ADDRESS6_TEXT_MAX_LEN) {
1176 isc_throw(BadValue, "address " << address_ << " of length " << address_.size()
1177 << " exceeds maximum allowed length of " << ADDRESS6_TEXT_MAX_LEN);
1178 }
1179
1180 // valid lifetime: bigint
1181 valid_lifetime_ = static_cast<cass_int64_t>(lease_->valid_lft_);
1182
1183 // expire: bigint
1184 // The lease structure holds the client last transmission time
1185 // (cltt_)
1186 // For convenience for external tools, this is converted to lease
1187 // expiry time (expire). The relationship is given by:
1188 // expire = cltt_ + valid_lft_
1189 CqlExchange::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
1190 expire_);
1191
1192 // subnet_id: int
1193 subnet_id_ = static_cast<cass_int32_t>(lease_->subnet_id_);
1194
1195 // pref_lifetime: bigint
1196 pref_lifetime_ = static_cast<cass_int64_t>(lease_->preferred_lft_);
1197
1198 // duid: blob
1199 if (!lease_->duid_) {
1200 isc_throw(DbOperationError, "lease6 with address " << address_
1201 << " is missing mandatory duid");
1202 }
1203 duid_ = lease_->duid_->getDuid();
1204
1205 // iaid: int
1206 iaid_ = static_cast<cass_int32_t>(lease_->iaid_);
1207
1208 // lease_type: int
1209 lease_type_ = static_cast<cass_int32_t>(lease_->type_);
1210
1211 // prefix_len: int
1212 prefix_len_ = static_cast<cass_int32_t>(lease_->prefixlen_);
1213
1214 // fqdn_fwd: boolean
1215 fqdn_fwd_ = lease_->fqdn_fwd_ ? cass_true : cass_false;
1216
1217 // fqdn_rev: boolean
1218 fqdn_rev_ = lease_->fqdn_rev_ ? cass_true : cass_false;
1219
1220 // hostname: varchar
1221 if (lease_->hostname_.size() > HOSTNAME_MAX_LEN) {
1222 isc_throw(BadValue, "hostname" << lease_->hostname_ << " of length "
1223 << lease_->hostname_.size() << " exceeds maximum allowed length of "
1224 << HOSTNAME_MAX_LEN);
1225 }
1226 hostname_ = lease_->hostname_;
1227
1228 // hwaddr: blob
1229 if (lease_->hwaddr_ && lease_->hwaddr_->hwaddr_.size() > 0) {
1230 if (lease_->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
1231 isc_throw(DbOperationError, "hardware address " << lease_->hwaddr_->toText()
1232 << " of length " << lease_->hwaddr_->hwaddr_.size()
1233 << " exceeds maximum allowed length of " << HWAddr::MAX_HWADDR_LEN);
1234 }
1235 hwaddr_ = lease_->hwaddr_->hwaddr_;
1236 } else {
1237 hwaddr_.clear();
1238 }
1239
1240 // hwtype: int
1241 if (lease_->hwaddr_) {
1242 hwtype_ = static_cast<cass_int32_t>(lease_->hwaddr_->htype_);
1243 } else {
1244 hwtype_ = 0;
1245 }
1246
1247 // hwaddr_source: int
1248 if (lease_->hwaddr_) {
1249 hwaddr_source_ = static_cast<cass_int32_t>(lease_->hwaddr_->source_);
1250 } else {
1251 hwaddr_source_ = 0;
1252 }
1253
1254 // state: int
1255 state_ = static_cast<cass_int32_t>(lease_->state_);
1256
1257 // user_context: text
1258 ConstElementPtr ctx = lease_->getContext();
1259 if (ctx) {
1260 user_context_ = ctx->str();
1261 } else {
1262 user_context_ = NULL_USER_CONTEXT;
1263 }
1264
1265 // Start with a fresh array.
1266 data.clear();
1267
1268 // Add them all to data.
1269 data.add(&address_);
1270 data.add(&valid_lifetime_);
1271 data.add(&expire_);
1272 data.add(&subnet_id_);
1273 data.add(&pref_lifetime_);
1274 data.add(&duid_);
1275 data.add(&iaid_);
1276 data.add(&lease_type_);
1277 data.add(&prefix_len_);
1278 data.add(&fqdn_fwd_);
1279 data.add(&fqdn_rev_);
1280 data.add(&hostname_);
1281 data.add(&hwaddr_);
1282 data.add(&hwtype_);
1283 data.add(&hwaddr_source_);
1284 data.add(&state_);
1285 data.add(&user_context_);
1286
1287 } catch (const Exception &ex) {
1288 isc_throw(DbOperationError, "CqlLease6Exchange::createBindForInsert(): "
1289 "could not create bind array from Lease6: " << lease_->addr_.toText()
1290 << ", reason: " << ex.what());
1291 }
1292}
1293
1294void
1296 StatementTag /* unused */) {
1297 if (!lease) {
1298 isc_throw(BadValue, "CqlLease6Exchange::createBindForUpdate(): "
1299 "Lease6 object is NULL");
1300 }
1301 // Store lease object to ensure it remains valid.
1302 lease_ = lease;
1303
1304 // Set up the structures for the various components of the lease4
1305 // structure.
1306 try {
1307 // address: varchar
1308 address_ = lease_->addr_.toText();
1309 if (address_.size() > ADDRESS6_TEXT_MAX_LEN) {
1311 "address " << address_ << " of length " << address_.size()
1312 << " exceeds maximum allowed length of "
1313 << ADDRESS6_TEXT_MAX_LEN);
1314 }
1315
1316 // valid lifetime: bigint
1317 valid_lifetime_ = static_cast<cass_int64_t>(lease_->valid_lft_);
1318
1319 // expire: bigint
1320 // The lease structure holds the client last transmission time
1321 // (cltt_)
1322 // For convenience for external tools, this is converted to lease
1323 // expiry time (expire). The relationship is given by:
1324 // expire = cltt_ + valid_lft_
1325 CqlExchange::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
1326 expire_);
1327
1328 // subnet_id: int
1329 subnet_id_ = static_cast<cass_int32_t>(lease_->subnet_id_);
1330
1331 // pref_lifetime: bigint
1332 pref_lifetime_ = static_cast<cass_int64_t>(lease_->preferred_lft_);
1333
1334 // duid: blob
1335 if (!lease_->duid_) {
1337 "lease6 with address " << address_
1338 << " is missing mandatory duid");
1339 }
1340 duid_ = lease_->duid_->getDuid();
1341
1342 // iaid: int
1343 iaid_ = static_cast<cass_int32_t>(lease_->iaid_);
1344
1345 // lease_type: int
1346 lease_type_ = static_cast<cass_int32_t>(lease_->type_);
1347
1348 // prefix_len: int
1349 prefix_len_ = static_cast<cass_int32_t>(lease_->prefixlen_);
1350
1351 // fqdn_fwd: boolean
1352 fqdn_fwd_ = lease_->fqdn_fwd_ ? cass_true : cass_false;
1353
1354 // fqdn_rev: boolean
1355 fqdn_rev_ = lease_->fqdn_rev_ ? cass_true : cass_false;
1356
1357 // hostname: varchar
1358 if (lease_->hostname_.size() > HOSTNAME_MAX_LEN) {
1360 "hostname" << lease_->hostname_ << " of length "
1361 << lease_->hostname_.size()
1362 << " exceeds maximum allowed length of "
1363 << HOSTNAME_MAX_LEN);
1364 }
1365 hostname_ = lease_->hostname_;
1366
1367 // hwaddr: blob
1368 if (lease_->hwaddr_ && lease_->hwaddr_->hwaddr_.size() > 0) {
1369 if (lease_->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
1371 "hardware address "
1372 << lease_->hwaddr_->toText() << " of length "
1373 << lease_->hwaddr_->hwaddr_.size()
1374 << " exceeds maximum allowed length of "
1376 }
1377 hwaddr_ = lease_->hwaddr_->hwaddr_;
1378 } else {
1379 hwaddr_.clear();
1380 }
1381
1382 // hwtype: int
1383 if (lease_->hwaddr_) {
1384 hwtype_ = static_cast<cass_int32_t>(lease_->hwaddr_->htype_);
1385 } else {
1386 hwtype_ = 0;
1387 }
1388
1389 // hwaddr_source: int
1390 if (lease_->hwaddr_) {
1391 hwaddr_source_ = static_cast<cass_int32_t>(lease_->hwaddr_->source_);
1392 } else {
1393 hwaddr_source_ = 0;
1394 }
1395
1396 // state: int
1397 state_ = static_cast<cass_int32_t>(lease_->state_);
1398
1399 // user_context: text
1400 ConstElementPtr ctx = lease_->getContext();
1401 if (ctx) {
1402 user_context_ = ctx->str();
1403 } else {
1404 user_context_ = NULL_USER_CONTEXT;
1405 }
1406
1407 // Start with a fresh array.
1408 data.clear();
1409
1410 // Add them all to data.
1411 data.add(&valid_lifetime_);
1412 data.add(&expire_);
1413 data.add(&pref_lifetime_);
1414 data.add(&duid_);
1415 data.add(&iaid_);
1416 data.add(&subnet_id_);
1417 data.add(&lease_type_);
1418 data.add(&prefix_len_);
1419 data.add(&fqdn_fwd_);
1420 data.add(&fqdn_rev_);
1421 data.add(&hostname_);
1422 data.add(&hwaddr_);
1423 data.add(&hwtype_);
1424 data.add(&hwaddr_source_);
1425 data.add(&state_);
1426 data.add(&user_context_);
1427 data.add(&address_);
1428
1429 CqlExchange::convertToDatabaseTime(lease_->current_cltt_,
1430 lease_->current_valid_lft_,
1432 data.add(&current_expire_);
1433 } catch (const Exception &ex) {
1435 "CqlLease6Exchange::createBindForUpdate(): "
1436 "could not create bind array from Lease6: "
1437 << lease_->addr_.toText() << ", reason: " << ex.what());
1438 }
1439}
1440
1441void
1443 StatementTag /* unused */) {
1444 if (!lease) {
1445 isc_throw(BadValue, "CqlLease6Exchange::createBindForDelete(): "
1446 "Lease6 object is NULL");
1447 }
1448 // Store lease object to ensure it remains valid.
1449 lease_ = lease;
1450
1451 // Set up the structures for the various components of the lease4
1452 // structure.
1453 try {
1454 // address: varchar
1455 address_ = lease_->addr_.toText();
1456 if (address_.size() > ADDRESS6_TEXT_MAX_LEN) {
1458 "address " << address_ << " of length " << address_.size()
1459 << " exceeds maximum allowed length of "
1460 << ADDRESS6_TEXT_MAX_LEN);
1461 }
1462
1463 // Start with a fresh array.
1464 data.clear();
1465 data.add(&address_);
1466
1467 CqlExchange::convertToDatabaseTime(lease_->current_cltt_,
1468 lease_->current_valid_lft_,
1470 data.add(&current_expire_);
1471 } catch (const Exception &ex) {
1473 "CqlLease6Exchange::createBindForDelete(): "
1474 "could not create bind array from Lease6: "
1475 << lease_->addr_.toText() << ", reason: " << ex.what());
1476 }
1477}
1478
1479void
1481 // Start with a fresh array.
1482 data.clear();
1483
1484 // address: varchar
1485 data.add(&address_);
1486
1487 // valid_lifetime_: bigint
1488 data.add(&valid_lifetime_);
1489
1490 // expire: bigint
1491 data.add(&expire_);
1492
1493 // subnet_id: int
1494 data.add(&subnet_id_);
1495
1496 // pref_lifetime: bigint
1497 data.add(&pref_lifetime_);
1498
1499 // duid: blob
1500 data.add(&duid_);
1501
1502 // iaid: int
1503 data.add(&iaid_);
1504
1505 // lease_type: int
1506 data.add(&lease_type_);
1507
1508 // prefix_len: int
1509 data.add(&prefix_len_);
1510
1511 // fqdn_fwd: boolean
1512 data.add(&fqdn_fwd_);
1513
1514 // fqdn_rev: boolean
1515 data.add(&fqdn_rev_);
1516
1517 // hostname: varchar
1518 data.add(&hostname_);
1519
1520 // hwaddr: blob
1521 data.add(&hwaddr_);
1522
1523 // hwtype: int
1524 data.add(&hwtype_);
1525
1526 // hwaddr_source: int
1527 data.add(&hwaddr_source_);
1528
1529 // state: int
1530 data.add(&state_);
1531
1532 // user_context: text
1533 data.add(&user_context_);
1534}
1535
1536boost::any
1538 try {
1539 // Sanity checks
1540 if (address_.size() > ADDRESS6_TEXT_MAX_LEN) {
1542 "address " << address_ << " of length " << address_.size()
1543 << " exceeds maximum allowed length of "
1544 << ADDRESS6_TEXT_MAX_LEN);
1545 }
1546 if (duid_.size() > DUID::MAX_DUID_LEN) {
1548 "duid " << DUID(duid_).toText() << " of length "
1549 << duid_.size()
1550 << " exceeds maximum allowed length of "
1552 }
1553 if (lease_type_ != Lease::TYPE_NA && lease_type_ != Lease::TYPE_TA &&
1554 lease_type_ != Lease::TYPE_PD) {
1556 "invalid lease type "
1557 << lease_type_ << " for lease with address "
1558 << address_ << ". Expected 0, 1 or 2.");
1559 }
1560 if (hostname_.size() > HOSTNAME_MAX_LEN) {
1562 "hostname " << hostname_ << " of length "
1563 << hostname_.size()
1564 << " exceeds maximum allowed length of "
1565 << HOSTNAME_MAX_LEN);
1566 }
1567 if (hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
1569 "hwaddr " << HWAddr(hwaddr_, hwtype_).toText(false)
1570 << " of length " << hwaddr_.size()
1571 << " exceeds maximum allowed length of "
1573 }
1574
1575 IOAddress addr(address_);
1576
1577 DuidPtr duid(boost::make_shared<DUID>(duid_));
1578
1579 HWAddrPtr hwaddr;
1580 if (hwaddr_.size()) {
1581 hwaddr = boost::make_shared<HWAddr>(hwaddr_, hwtype_);
1582 hwaddr->source_ = hwaddr_source_;
1583 }
1584
1585 ConstElementPtr ctx;
1586 if (!user_context_.empty()) {
1587 ctx = Element::fromJSON(user_context_);
1588 if (!ctx ||(ctx->getType() != Element::map)) {
1589 isc_throw(BadValue, "user context '" << user_context_
1590 << "' is not a JSON map");
1591 }
1592 }
1593
1594 // Create the lease and set the cltt (after converting from the
1595 // expire time retrieved from the database).
1596 Lease6Ptr result(boost::make_shared<Lease6>(static_cast<Lease::Type>(lease_type_), addr, duid,
1597 iaid_, pref_lifetime_, valid_lifetime_,
1599 hwaddr, prefix_len_));
1600
1601 time_t cltt = 0;
1603 // Update cltt_ and current_cltt_ explicitly.
1604 result->cltt_ = cltt;
1605 result->current_cltt_ = cltt;
1606
1607 result->state_ = state_;
1608
1609 if (ctx) {
1610 result->setContext(ctx);
1611 }
1612
1613 return (result);
1614 } catch (const Exception &ex) {
1616 "CqlLease6Exchange::retrieve(): "
1617 "could not convert data to Lease6, reason: "
1618 << ex.what());
1619 }
1620 return Lease6Ptr();
1621}
1622
1623void
1625 Lease6Collection &result) {
1626 AnyArray collection = executeSelect(connection_, data, statement_tag);
1627
1628 // Transfer Lease6 objects to result.
1629 for (boost::any &lease : collection) {
1630 result.push_back(boost::any_cast<Lease6Ptr>(lease));
1631 }
1632}
1633
1634void
1636 Lease6Ptr &result) {
1637 // This particular method is called when only one or zero matches is
1638 // expected.
1639 Lease6Collection collection;
1640 getLeaseCollection(statement_tag, data, collection);
1641
1642 // Return single record if present, else clear the lease.
1643 const size_t collection_size = collection.size();
1644 if (collection_size >= 2u) {
1646 "CqlLease6Exchange::getLease(): multiple records were found in "
1647 "the database where only one was expected for statement "
1648 << statement_tag);
1649 } else if (collection_size == 0u) {
1650 result.reset();
1651 } else {
1652 result = *collection.begin();
1653 }
1654}
1655
1656void
1658 Lease6Collection &expired_leases) {
1659 // Set up the WHERE clause value
1660 cass_int32_t keep_state = Lease::STATE_EXPIRED_RECLAIMED;
1661 cass_int64_t timestamp = static_cast<cass_int64_t>(time(NULL));
1662
1663 // If the number of leases is 0, we will return all leases. This is
1664 // achieved by setting the limit to a very high value.
1665 cass_int32_t limit = max_leases > 0u ? static_cast<cass_int32_t>(max_leases) :
1666 std::numeric_limits<cass_int32_t>::max();
1667
1668 for (cass_int32_t state = Lease::STATE_DEFAULT;
1669 state <= Lease::STATE_EXPIRED_RECLAIMED; ++state) {
1670 if (state == keep_state) {
1671 continue;
1672 }
1673
1674 AnyArray data;
1675 data.add(&state);
1676 data.add(&timestamp);
1677 data.add(&limit);
1678
1679 // Retrieve leases from the database.
1680 Lease6Collection temp_collection;
1682 temp_collection);
1683
1684 for (Lease6Ptr &lease : temp_collection) {
1685 expired_leases.push_back(lease);
1686 }
1687 }
1688}
1689
1696public:
1697
1707 const bool fetch_type)
1708 : conn_(conn), statement_(statement), fetch_type_(fetch_type),
1709 cumulative_rows_(), next_row_(cumulative_rows_.begin()),
1710 subnet_id_(0), lease_type_(0), state_(0) {
1711 }
1712
1723 const bool fetch_type, const SubnetID& subnet_id)
1724 : LeaseStatsQuery(subnet_id), conn_(conn), statement_(statement),
1725 fetch_type_(fetch_type), cumulative_rows_(),
1726 next_row_(cumulative_rows_.begin()),
1727 subnet_id_(0), lease_type_(0), state_(0) {
1728 }
1729
1742 const bool fetch_type, const SubnetID& first_subnet_id,
1743 const SubnetID& last_subnet_id)
1744 : LeaseStatsQuery(first_subnet_id, last_subnet_id), conn_(conn),
1745 statement_(statement), fetch_type_(fetch_type), cumulative_rows_(),
1746 next_row_(cumulative_rows_.begin()),
1747 subnet_id_(0), lease_type_(0), state_(0) {
1748 }
1749
1752
1759 void start();
1760
1787 void executeSelect(const CqlConnection& connection, const AnyArray& data,
1788 StatementTag statement_tag);
1789
1801 bool getNextRow(LeaseStatsRow& row);
1802
1810 virtual void
1811 createBindForSelect(AnyArray& data, StatementTag statement_tag = NULL);
1812
1815 // Return lease4 lease statistics for all subnets
1816 static constexpr StatementTag ALL_LEASE4_STATS = "ALL_LEASE4_STATS";
1818 static constexpr StatementTag SUBNET_LEASE4_STATS = "SUBNET_LEASE4_STATS";
1820 static constexpr StatementTag SUBNET_RANGE_LEASE4_STATS = "SUBNET_RANGE_LEASE4_STATS";
1821
1822 // Return lease6 lease statistics for all subnets
1823 static constexpr StatementTag ALL_LEASE6_STATS = "ALL_LEASE6_STATS";
1825 static constexpr StatementTag SUBNET_LEASE6_STATS = "SUBNET_LEASE6_STATS";
1827 static constexpr StatementTag SUBNET_RANGE_LEASE6_STATS = "SUBNET_RANGE_LEASE6_STATS";
1829
1832
1833private:
1834
1836 CqlConnection& conn_;
1837
1839 StatementTag statement_;
1840
1842 bool fetch_type_;
1843
1844
1846 std::map<LeaseStatsRow, int> cumulative_rows_;
1847
1849 std::map<LeaseStatsRow, int>::iterator next_row_;
1850
1852 cass_int32_t subnet_id_;
1853
1855 cass_int32_t lease_type_;
1856
1858 cass_int32_t state_;
1859};
1860
1867
1869 // Return subnet_id and state of each v4 lease
1870 {ALL_LEASE4_STATS,
1871 {ALL_LEASE4_STATS,
1872 "SELECT "
1873 "subnet_id, state "
1874 "FROM lease4 "
1875 }},
1876
1877 // Return state of each v4 lease for a single subnet
1878 {SUBNET_LEASE4_STATS,
1879 {SUBNET_LEASE4_STATS,
1880 "SELECT "
1881 "subnet_id, state "
1882 "FROM lease4 "
1883 "WHERE subnet_id = ? "
1884 }},
1885
1886 // Return state of each v4 lease for a subnet range
1887 {SUBNET_RANGE_LEASE4_STATS,
1888 {SUBNET_RANGE_LEASE4_STATS,
1889 "SELECT "
1890 "subnet_id, state "
1891 "FROM lease4 "
1892 "WHERE subnet_id >= ? and subnet_id <= ? "
1893 "ALLOW FILTERING "
1894 }},
1895
1896 // Return subnet_id, lease_type, and state of each v6 lease
1897 {ALL_LEASE6_STATS,
1898 {ALL_LEASE6_STATS,
1899 "SELECT "
1900 "subnet_id, lease_type, state "
1901 "FROM lease6 "
1902 }},
1903
1904 // Return type and state of each v6 lease for a single subnet
1905 {SUBNET_LEASE6_STATS,
1906 {SUBNET_LEASE6_STATS,
1907 "SELECT "
1908 "subnet_id, lease_type, state "
1909 "FROM lease6 "
1910 "WHERE subnet_id = ? "
1911 }},
1912
1913 // Return type and state of each v6 lease for single range
1914 {SUBNET_RANGE_LEASE6_STATS,
1915 {SUBNET_RANGE_LEASE6_STATS,
1916 "SELECT "
1917 "subnet_id, lease_type, state "
1918 "FROM lease6 "
1919 "WHERE subnet_id >= ? and subnet_id <= ? "
1920 "ALLOW FILTERING "
1921 }},
1922};
1923
1924void
1926 // Set up where clause parameters as needed
1927 AnyArray data;
1928 cass_int32_t first_subnet_id_data;
1929 cass_int32_t last_subnet_id_data;
1930 if (getSelectMode() != ALL_SUBNETS) {
1931 first_subnet_id_data = static_cast<cass_int32_t>(first_subnet_id_);
1932 data.add(&first_subnet_id_data);
1933
1934 if (getSelectMode() == SUBNET_RANGE) {
1935 last_subnet_id_data = static_cast<cass_int32_t>(last_subnet_id_);
1936 data.add(&last_subnet_id_data);
1937 }
1938 }
1939
1940 // This gets a collection of "raw" data for all leases that match
1941 // the subnet selection criteria (all, range, or single subnets)
1942 // then rolls them up into cumulative_rows_
1943 executeSelect(conn_, data, statement_);
1944
1945 // Set our row iterator to the beginning
1946 next_row_ = cumulative_rows_.begin();
1947}
1948
1949bool
1951 // If we're past the end, punt.
1952 if (next_row_ == cumulative_rows_.end()) {
1953 return (false);
1954 }
1955
1956 // Start by copying from the map row key
1957 row.subnet_id_ = next_row_->first.subnet_id_;
1958 row.lease_type_ = next_row_->first.lease_type_;
1959 row.lease_state_ = next_row_->first.lease_state_;
1960
1961 // Grab the count from the map value
1962 row.state_count_ = next_row_->second;
1963
1964 // Point to the next row.
1965 ++next_row_;
1966 return (true);
1967}
1968
1969void
1971 data.clear();
1972 data.add(&subnet_id_);
1973 if (fetch_type_) {
1974 data.add(&lease_type_);
1975 }
1976
1977 data.add(&state_);
1978}
1979
1980void
1982 StatementTag statement_tag) {
1983 CassError rc;
1984 CassStatement* statement = NULL;
1985 CassFuture* future = NULL;
1986 AnyArray local_data = data;
1987
1988 // Find the query statement first.
1989 StatementMap::const_iterator it = connection.statements_.find(statement_tag);
1990 if (it == connection.statements_.end()) {
1992 "CqlLeastStatsQuery::executeSelect(): Statement "
1993 << statement_tag << "has not been prepared.");
1994 }
1995
1996 // Bind the data before the query is executed.
1997 CqlTaggedStatement tagged_statement = it->second;
1998 if (tagged_statement.is_raw_) {
1999 // The entire query is the first element in data.
2000 std::string* query = boost::any_cast<std::string*>(local_data.back());
2001 local_data.pop_back();
2002 statement = cass_statement_new(query->c_str(), local_data.size());
2003 } else {
2004 statement = cass_prepared_bind(tagged_statement.prepared_statement_);
2005 if (!statement) {
2007 "CqlLeaseStatsQuery::executeSelect(): unable to bind statement "
2008 << tagged_statement.name_);
2009 }
2010 }
2011
2012 // Set specific level of consistency if we're told to do so.
2013 if (connection.force_consistency_) {
2014 rc = cass_statement_set_consistency(statement, connection.consistency_);
2015 if (rc != CASS_OK) {
2016 cass_statement_free(statement);
2018 "CqlLeaseStatsQuery::executeSelect(): unable to set statement "
2019 "consistency for statement "
2020 << tagged_statement.name_
2021 << ", Cassandra error code: " << cass_error_desc(rc));
2022 }
2023 if (connection.serial_consistency_ != CASS_CONSISTENCY_UNKNOWN) {
2024 rc = cass_statement_set_serial_consistency(statement, connection.serial_consistency_);
2025 if (rc != CASS_OK) {
2026 cass_statement_free(statement);
2028 "CqlExchange::executeSelect(): unable to set statement "
2029 "serial consistency for statement "
2030 << tagged_statement.name_
2031 << ", Cassandra error code: " << cass_error_desc(rc));
2032 }
2033 }
2034 }
2035
2036 CqlCommon::bindData(local_data, statement);
2037
2038 // Everything's ready. Call the actual statement.
2039 future = cass_session_execute(connection.session_, statement);
2040 if (!future) {
2041 cass_statement_free(statement);
2043 "CqlLeaseStatsQuery::executeSelect(): no CassFuture for statement "
2044 << tagged_statement.name_);
2045 }
2046
2047 // Wait for the statement execution to complete.
2048 cass_future_wait(future);
2049 const std::string error = connection.checkFutureError(
2050 "CqlLeaseStatsQuery::executeSelect(): cass_session_execute() != CASS_OK",
2051 future, statement_tag);
2052 rc = cass_future_error_code(future);
2053 if (rc != CASS_OK) {
2054 cass_future_free(future);
2055 cass_statement_free(statement);
2057 }
2058
2059 // Get column values.
2060 const CassResult* result_collection = cass_future_get_result(future);
2061
2062 // lease type is always NA for v4
2063 if (!fetch_type_) {
2064 lease_type_ = Lease::TYPE_NA;
2065 }
2066
2067 // Since we're currently forced to pull data for all leases, we
2068 // iterate over them, aggregating them into cumulative LeaseStatsRows
2069 AnyArray return_values;
2070 CassIterator* rows = cass_iterator_from_result(result_collection);
2071 while (cass_iterator_next(rows)) {
2072 const CassRow* row = cass_iterator_get_row(rows);
2073 createBindForSelect(return_values, statement_tag);
2074 CqlCommon::getData(row, return_values);
2075
2076 if (state_ != Lease::STATE_DEFAULT &&
2077 state_ != Lease::STATE_DECLINED) {
2078 continue;
2079 }
2080
2081 LeaseStatsRow raw_row(subnet_id_, static_cast<Lease::Type>(lease_type_),
2082 state_, 1);
2083
2084 auto cum_row = cumulative_rows_.find(raw_row);
2085 if (cum_row != cumulative_rows_.end()) {
2086 cumulative_rows_[raw_row] = cum_row->second + 1;
2087 } else {
2088 cumulative_rows_.insert(std::make_pair(raw_row, 1));
2089 }
2090 }
2091
2092 // Free resources.
2093 cass_iterator_free(rows);
2094 cass_result_free(result_collection);
2095 cass_future_free(future);
2096 cass_statement_free(statement);
2097 return;
2098}
2099
2101 : parameters_(parameters), dbconn_(parameters) {
2102 // Validate the schema version first.
2103 std::pair<uint32_t, uint32_t> code_version(CQL_SCHEMA_VERSION_MAJOR,
2105 std::pair<uint32_t, uint32_t> db_version = getVersion();
2106 if (code_version != db_version) {
2107 isc_throw(DbOpenError, "Cassandra schema version mismatch: need version: "
2108 << code_version.first << "." << code_version.second
2109 << " found version: " << db_version.first << "."
2110 << db_version.second);
2111 }
2112
2113 // Cassandra support is now deprecated.
2114 LOG_WARN(dhcpsrv_logger, DHCPSRV_DEPRECATED).arg("Cassandra lease backend");
2115
2116 // Open the database.
2117 dbconn_.openDatabase();
2118
2119 // Now prepare the rest of the exchanges.
2123}
2124
2126 // There is no need to close the database in this destructor: it is
2127 // closed in the destructor of the dbconn_ member variable.
2128}
2129
2130std::string
2132 std::stringstream tmp;
2133 tmp << "CQL backend " << CQL_SCHEMA_VERSION_MAJOR;
2134 tmp << "." << CQL_SCHEMA_VERSION_MINOR;
2135 tmp << ", library cassandra";
2136 return tmp.str();
2137}
2138
2139bool
2142 .arg(lease->addr_.toText());
2143
2144 AnyArray data;
2145
2146 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2147 exchange4->createBindForInsert(lease, data);
2148 try {
2149 exchange4->executeMutation(dbconn_, data, CqlLease4Exchange::INSERT_LEASE4);
2150 } catch (const Exception &exception) {
2152 .arg(exception.what());
2153 return false;
2154 }
2155
2156 // Update lease current expiration time (allows update between the creation
2157 // of the Lease up to the point of insertion in the database).
2158 lease->updateCurrentExpirationTime();
2159
2160 return true;
2161}
2162
2163bool
2166 .arg(lease->addr_.toText());
2167
2168 AnyArray data;
2169
2170 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2171 exchange6->createBindForInsert(lease, data);
2172 try {
2173 exchange6->executeMutation(dbconn_, data, CqlLease6Exchange::INSERT_LEASE6);
2174 } catch (const Exception &exception) {
2176 .arg(exception.what());
2177 return false;
2178 }
2179
2180 // Update lease current expiration time (allows update between the creation
2181 // of the Lease up to the point of insertion in the database).
2182 lease->updateCurrentExpirationTime();
2183
2184 return true;
2185}
2186
2190 .arg(addr.toText());
2191
2192 // Set up the WHERE clause value
2193 AnyArray data;
2194
2195 cass_int32_t addr4 = static_cast<cass_int32_t>(addr.toUint32());
2196 data.add(&addr4);
2197
2198 // Get the data.
2199 Lease4Ptr result;
2200
2201 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2202 exchange4->getLease(CqlLease4Exchange::GET_LEASE4_ADDR, data, result);
2203
2204 return (result);
2205}
2206
2208CqlLeaseMgr::getLease4(const HWAddr &hwaddr) const {
2210 .arg(hwaddr.toText());
2211
2212 // Set up the WHERE clause value
2213 AnyArray data;
2214
2215 CassBlob hwaddr_data(hwaddr.hwaddr_);
2216 data.add(&hwaddr_data);
2217
2218 // Get the data.
2219 Lease4Collection result;
2220 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2221 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_HWADDR, data, result);
2222
2223 return (result);
2224}
2225
2227CqlLeaseMgr::getLease4(const HWAddr &hwaddr, SubnetID subnet_id) const {
2230 .arg(subnet_id)
2231 .arg(hwaddr.toText());
2232
2233 // Set up the WHERE clause value
2234 AnyArray data;
2235
2236 CassBlob hwaddr_data(hwaddr.hwaddr_);
2237 data.add(&hwaddr_data);
2238
2239 cass_int32_t subnet_id_data = static_cast<cass_int32_t>(subnet_id);
2240 data.add(&subnet_id_data);
2241
2242 // Get the data.
2243 Lease4Ptr result;
2244 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2245 exchange4->getLease(CqlLease4Exchange::GET_LEASE4_HWADDR_SUBID, data, result);
2246
2247 return (result);
2248}
2249
2251CqlLeaseMgr::getLease4(const ClientId &clientid) const {
2253 .arg(clientid.toText());
2254
2255 // Set up the WHERE clause value
2256 AnyArray data;
2257
2258 CassBlob client_id_data(clientid.getClientId());
2259 data.add(&client_id_data);
2260
2261 // Get the data.
2262 Lease4Collection result;
2263 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2264 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_CLIENTID, data, result);
2265
2266 return (result);
2267}
2268
2270CqlLeaseMgr::getLease4(const ClientId &clientid, SubnetID subnet_id) const {
2272 .arg(subnet_id)
2273 .arg(clientid.toText());
2274
2275 // Set up the WHERE clause value
2276 AnyArray data;
2277
2278 CassBlob client_id_data(clientid.getClientId());
2279 data.add(&client_id_data);
2280
2281 cass_int32_t subnet_id_data = static_cast<cass_int32_t>(subnet_id);
2282 data.add(&subnet_id_data);
2283
2284 // Get the data.
2285 Lease4Ptr result;
2286 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2287 exchange4->getLease(CqlLease4Exchange::GET_LEASE4_CLIENTID_SUBID, data, result);
2288
2289 return (result);
2290}
2291
2295 .arg(subnet_id);
2296
2297 // Set up the WHERE clause value
2298 AnyArray data;
2299
2300 cass_int32_t subnet_id_data = static_cast<cass_int32_t>(subnet_id);
2301 data.add(&subnet_id_data);
2302
2303 // Get the data.
2304 Lease4Collection result;
2305 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2306 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_SUBID, data, result);
2307
2308 return (result);
2309}
2310
2312CqlLeaseMgr::getLeases4(const std::string& hostname) const {
2314 .arg(hostname);
2315
2316 // Set up the WHERE clause value
2317 AnyArray data;
2318
2319 std::string hostname_data(hostname);
2320 data.add(&hostname_data);
2321
2322 // Get the data.
2323 Lease4Collection result;
2324 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2325 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_HOSTNAME, data, result);
2326
2327 return (result);
2328}
2329
2333
2334 // Set up the WHERE clause value
2335 AnyArray data;
2336
2337 // Get the data.
2338 Lease4Collection result;
2339 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2340 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4, data, result);
2341
2342 return (result);
2343}
2344
2347 const LeasePageSize& page_size) const {
2348 // Expecting IPv4 address.
2349 if (!lower_bound_address.isV4()) {
2350 isc_throw(InvalidAddressFamily, "expected IPv4 address while "
2351 "retrieving leases from the lease database, got "
2352 << lower_bound_address);
2353 }
2354
2355 if (page_size.page_size_ == 0) {
2356 isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
2357 }
2358
2359 if (page_size.page_size_ > std::numeric_limits<uint32_t>::max()) {
2360 isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
2361 << std::numeric_limits<uint32_t>::max());
2362 }
2363
2365 .arg(page_size.page_size_)
2366 .arg(lower_bound_address.toText());
2367
2368 AnyArray data;
2369
2370 cass_int32_t address_data = 0;
2371 if (!lower_bound_address.isV4Zero()) {
2372 address_data = static_cast<cass_int32_t>(lower_bound_address.toUint32());
2373 data.add(&address_data);
2374 }
2375
2376 cass_int32_t page_size_data = static_cast<cass_int32_t>(page_size.page_size_);
2377 data.add(&page_size_data);
2378
2379 // Get the data.
2380 Lease4Collection result;
2381 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2382 exchange4->getLeaseCollection(lower_bound_address.isV4Zero() ?
2385 data, result);
2386
2387 return (result);
2388}
2389
2391CqlLeaseMgr::getLease6(Lease::Type lease_type, const IOAddress &addr) const {
2392 std::string addr_data = addr.toText();
2394 .arg(addr_data)
2395 .arg(lease_type);
2396
2397 // Set up the WHERE clause value
2398 AnyArray data;
2399
2400 if (addr_data.size() > ADDRESS6_TEXT_MAX_LEN) {
2402 "CqlLeaseMgr::getLease6(): "
2403 "address "
2404 << addr_data << " of length " << addr_data.size()
2405 << " exceeds maximum allowed length of "
2406 << ADDRESS6_TEXT_MAX_LEN);
2407 }
2408 data.add(&addr_data);
2409
2410 cass_int32_t lease_type_data = static_cast<cass_int32_t>(lease_type);
2411 data.add(&lease_type_data);
2412
2413 Lease6Ptr result;
2414 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2415 exchange6->getLease(CqlLease6Exchange::GET_LEASE6_ADDR, data, result);
2416
2417 return (result);
2418}
2419
2421CqlLeaseMgr::getLeases6(const DUID& duid) const {
2422
2423 // Set up the WHERE clause value
2424 AnyArray data;
2425
2426 CassBlob duid_data(duid.getDuid());
2427
2428 data.add(&duid_data);
2429
2430 // Get the data.
2431 Lease6Collection result;
2432 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2433 exchange6->getLeaseCollection(CqlLease6Exchange::GET_LEASE6_DUID,
2434 data, result);
2435
2436 return (result);
2437}
2438
2440CqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID &duid, uint32_t iaid) const {
2442 .arg(iaid)
2443 .arg(duid.toText())
2444 .arg(lease_type);
2445
2446 // Set up the WHERE clause value
2447 AnyArray data;
2448
2449 CassBlob duid_data(duid.getDuid());
2450 cass_int32_t iaid_data = static_cast<cass_int32_t>(iaid);
2451
2452 data.add(&duid_data);
2453 data.add(&iaid_data);
2454
2455 cass_int32_t lease_type_data = static_cast<cass_int32_t>(lease_type);
2456 data.add(&lease_type_data);
2457
2458 // Get the data.
2459 Lease6Collection result;
2460 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2461 exchange6->getLeaseCollection(CqlLease6Exchange::GET_LEASE6_DUID_IAID, data, result);
2462
2463 return (result);
2464}
2465
2467CqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID &duid, uint32_t iaid,
2468 SubnetID subnet_id) const {
2470 .arg(iaid)
2471 .arg(subnet_id)
2472 .arg(duid.toText())
2473 .arg(lease_type);
2474
2475 // Set up the WHERE clause value
2476 AnyArray data;
2477
2478 CassBlob duid_data(duid.getDuid());
2479 cass_int32_t iaid_data = static_cast<cass_int32_t>(iaid);
2480
2481 data.add(&duid_data);
2482 data.add(&iaid_data);
2483
2484 cass_int32_t lease_type_data = static_cast<cass_int32_t>(lease_type);
2485 data.add(&lease_type_data);
2486
2487 cass_int32_t subnet_id_data = static_cast<cass_int32_t>(subnet_id);
2488 data.add(&subnet_id_data);
2489
2490 // Get the data.
2491 Lease6Collection result;
2492 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2493 exchange6->getLeaseCollection(CqlLease6Exchange::GET_LEASE6_DUID_IAID_SUBID, data, result);
2494
2495 return (result);
2496}
2497
2500 isc_throw(NotImplemented, "getLeases6(subnet_id) is not implemented");
2501}
2502
2504CqlLeaseMgr::getLeases6(const std::string& hostname) const {
2506 .arg(hostname);
2507
2508 // Set up the WHERE clause value
2509 AnyArray data;
2510
2511 std::string hostname_data(hostname);
2512 data.add(&hostname_data);
2513
2514 // Get the data.
2515 Lease6Collection result;
2516 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2517 exchange6->getLeaseCollection(CqlLease6Exchange::GET_LEASE6_HOSTNAME, data, result);
2518
2519 return (result);
2520}
2521
2524 isc_throw(NotImplemented, "getLeases6() is not implemented");
2525}
2526
2529 const LeasePageSize& page_size) const {
2530 // Expecting IPv6 address.
2531 if (!lower_bound_address.isV6()) {
2532 isc_throw(InvalidAddressFamily, "expected IPv6 address while "
2533 "retrieving leases from the lease database, got "
2534 << lower_bound_address);
2535 }
2536
2537 if (page_size.page_size_ == 0) {
2538 isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
2539 }
2540
2541 if (page_size.page_size_ > std::numeric_limits<uint32_t>::max()) {
2542 isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
2543 << std::numeric_limits<uint32_t>::max());
2544 }
2545
2547 .arg(page_size.page_size_)
2548 .arg(lower_bound_address.toText());
2549
2550 AnyArray data;
2551
2552 std::string lb_address_data;
2553 if (!lower_bound_address.isV6Zero()) {
2554 lb_address_data = lower_bound_address.toText();
2555 if (lb_address_data.size() > ADDRESS6_TEXT_MAX_LEN) {
2557 "CqlLeaseMgr::getLeases6(lower_bound_address, page_size): "
2558 "address "
2559 << lb_address_data << " of length " << lb_address_data.size()
2560 << " exceeds maximum allowed length of "
2561 << ADDRESS6_TEXT_MAX_LEN);
2562 }
2563 data.add(&lb_address_data);
2564 }
2565
2566 cass_int32_t page_size_data = static_cast<cass_int32_t>(page_size.page_size_);
2567 data.add(&page_size_data);
2568
2569 // Get the leases.
2570 Lease6Collection result;
2571 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2572 exchange6->getLeaseCollection(lower_bound_address.isV6Zero() ?
2575 data, result);
2576
2577 return (result);
2578}
2579
2580void
2582 const size_t max_leases) const {
2584 .arg(max_leases);
2585
2586 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2587 exchange4->getExpiredLeases(max_leases, expired_leases);
2588}
2589
2590void
2592 const size_t max_leases) const {
2594 .arg(max_leases);
2595
2596 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2597 exchange6->getExpiredLeases(max_leases, expired_leases);
2598}
2599
2600void
2603 .arg(lease->addr_.toText());
2604
2605 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2606
2607 try {
2608 AnyArray data;
2609 exchange4->createBindForUpdate(lease, data, CqlLease4Exchange::UPDATE_LEASE4);
2610 exchange4->executeMutation(dbconn_, data, CqlLease4Exchange::UPDATE_LEASE4);
2611 } catch (const StatementNotApplied &exception) {
2612 isc_throw(NoSuchLease, exception.what());
2613 }
2614
2615 // Update lease current expiration time.
2616 lease->updateCurrentExpirationTime();
2617}
2618
2619void
2622 .arg(lease->addr_.toText());
2623
2624 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2625
2626 try {
2627 AnyArray data;
2628 exchange6->createBindForUpdate(lease, data, CqlLease6Exchange::UPDATE_LEASE6);
2629 exchange6->executeMutation(dbconn_, data, CqlLease6Exchange::UPDATE_LEASE6);
2630 } catch (const StatementNotApplied &exception) {
2631 isc_throw(NoSuchLease, exception.what());
2632 }
2633
2634 // Update lease current expiration time.
2635 lease->updateCurrentExpirationTime();
2636}
2637
2638bool
2640 const IOAddress &addr = lease->addr_;
2641 std::string addr_data = addr.toText();
2643 .arg(addr_data);
2644
2645 // Set up the WHERE clause value
2646 AnyArray data;
2647
2648 std::unique_ptr<CqlLease4Exchange> exchange4(
2649 new CqlLease4Exchange(dbconn_));
2650
2651 try {
2652 exchange4->createBindForDelete(lease, data, CqlLease4Exchange::DELETE_LEASE4);
2653 exchange4->executeMutation(dbconn_, data, CqlLease4Exchange::DELETE_LEASE4);
2654 } catch (const Exception &exception) {
2656 .arg(exception.what());
2657 return false;
2658 }
2659 return true;
2660}
2661
2662bool
2664 const IOAddress &addr = lease->addr_;
2665 std::string addr_data = addr.toText();
2667 .arg(addr_data);
2668
2669 // Set up the WHERE clause value
2670 AnyArray data;
2671
2672 std::unique_ptr<CqlLease6Exchange> exchange6(
2673 new CqlLease6Exchange(dbconn_));
2674
2675 try {
2676 exchange6->createBindForDelete(lease, data, CqlLease6Exchange::DELETE_LEASE6);
2677 exchange6->executeMutation(dbconn_, data, CqlLease6Exchange::DELETE_LEASE6);
2678 } catch (const Exception &exception) {
2680 .arg(exception.what());
2681 return false;
2682 }
2683 return true;
2684}
2685
2686uint64_t
2690 .arg(secs);
2691 AnyArray data;
2692 uint64_t deleted = 0u;
2693 cass_int32_t limit = 1024;
2694
2695 // State is reclaimed.
2696 cass_int32_t state = static_cast<cass_int32_t>(Lease::STATE_EXPIRED_RECLAIMED);
2697 data.add(&state);
2698
2699 // Expiration timestamp.
2700 cass_int64_t expiration = static_cast<cass_int64_t>(time(NULL) - static_cast<time_t>(secs));
2701 data.add(&expiration);
2702
2703 data.add(&limit);
2704
2705 // Get the data.
2706 Lease4Collection leases;
2707 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2708 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_EXPIRE, data, leases);
2709 for (Lease4Ptr &lease : leases) {
2710 if (deleteLease(lease)) {
2711 ++deleted;
2712 }
2713 }
2714 return (deleted);
2715}
2716
2717uint64_t
2721 .arg(secs);
2722 AnyArray data;
2723 uint64_t deleted = 0u;
2724 cass_int32_t limit = 1024;
2725
2726 // State is reclaimed.
2727 cass_int32_t state = static_cast<cass_int32_t>(Lease::STATE_EXPIRED_RECLAIMED);
2728 data.add(&state);
2729
2730 // Expiration timestamp.
2731 cass_int64_t expiration = static_cast<cass_int64_t>(time(NULL) - static_cast<time_t>(secs));
2732 data.add(&expiration);
2733
2734 data.add(&limit);
2735
2736 // Get the data.
2737 Lease6Collection leases;
2738 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2739 exchange6->getLeaseCollection(CqlLease6Exchange::GET_LEASE6_EXPIRE, data, leases);
2740 for (Lease6Ptr &lease : leases) {
2741 if (deleteLease(lease)) {
2742 ++deleted;
2743 }
2744 }
2745 return (deleted);
2746}
2747
2750 LeaseStatsQueryPtr query(
2752 false));
2753 query->start();
2754 return(query);
2755}
2756
2759 LeaseStatsQueryPtr query(
2761 false, subnet_id));
2762 query->start();
2763 return(query);
2764}
2765
2768 const SubnetID& last_subnet_id) {
2769 LeaseStatsQueryPtr query(
2771 false, first_subnet_id, last_subnet_id));
2772 query->start();
2773 return(query);
2774}
2775
2778 LeaseStatsQueryPtr query(
2780 true));
2781 query->start();
2782 return(query);
2783}
2784
2787 LeaseStatsQueryPtr query(
2789 true, subnet_id));
2790 query->start();
2791 return(query);
2792}
2793
2796 const SubnetID& last_subnet_id) {
2797 LeaseStatsQueryPtr query(
2799 true, first_subnet_id, last_subnet_id));
2800 query->start();
2801 return(query);
2802}
2803
2804size_t
2805CqlLeaseMgr::wipeLeases4(const SubnetID & /*subnet_id*/) {
2807 isc_throw(NotImplemented, "wipeLeases4 is not implemented for Cassandra backend");
2808}
2809
2810size_t
2811CqlLeaseMgr::wipeLeases6(const SubnetID & /*subnet_id*/) {
2813 isc_throw(NotImplemented, "wipeLeases6 is not implemented for Cassandra backend");
2814}
2815
2816std::string
2818 std::string name = "";
2819 try {
2820 name = dbconn_.getParameter("name");
2821 } catch (...) {
2822 // Return an empty name
2823 }
2824 return name;
2825}
2826
2827std::string
2829 return std::string("Cassandra Database");
2830}
2831
2835
2836 return CqlConnection::getVersion(parameters_);
2837}
2838
2839void
2842 dbconn_.commit();
2843}
2844
2845void
2848 dbconn_.rollback();
2849}
2850
2851} // namespace dhcp
2852} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when a function is not implemented.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Structure used to bind C++ input values to dynamic CQL parameters.
Definition: cql_exchange.h:50
void add(const boost::any &value)
Add a value at the end of the vector.
static void bindData(const AnyArray &data, CassStatement *statement)
Assigns values to every column of an INSERT or an UPDATE statement.
static void getData(const CassRow *row, AnyArray &data)
Retrieves data returned by Cassandra.
Common CQL connector pool.
StatementMap statements_
Pointer to external array of tagged statements containing statement name, array of names of bind para...
CassConsistency serial_consistency_
CQL serial consistency.
virtual void commit()
Commit Transactions.
virtual void rollback()
Rollback Transactions.
static std::pair< uint32_t, uint32_t > getVersion(const ParameterMap &parameters)
Get the schema version.
CassSession * session_
CQL session handle.
bool force_consistency_
CQL consistency enabled.
void openDatabase()
Open database.
CassConsistency consistency_
CQL consistency.
static const std::string checkFutureError(const std::string &what, CassFuture *future, StatementTag statement_tag=NULL)
Check for errors.
void prepareStatements(StatementMap &statements)
Prepare statements.
Cassandra Exchange.
Definition: cql_exchange.h:142
AnyArray executeSelect(const CqlConnection &connection, const AnyArray &where_values, StatementTag statement_tag, const bool &single=false)
Executes SELECT statements.
static void convertFromDatabaseTime(const cass_int64_t &expire, const cass_int64_t &valid_lifetime, time_t &cltt)
Converts time from Cassandra format.
static void convertToDatabaseTime(const time_t &cltt, const uint32_t &valid_lifetime, cass_int64_t &expire)
std::string getParameter(const std::string &name) const
Returns value of a connection parameter.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Exception thrown on failure to open database.
Exception thrown on failure to execute a database function.
Invalid address family used as input to Lease Manager.
Definition: db_exceptions.h:71
Multiple lease records found where one expected.
Definition: db_exceptions.h:28
Database statement not applied.
Definition: db_exceptions.h:20
Holds Client identifier or client IPv4 address.
Definition: duid.h:111
static const size_t MAX_CLIENT_ID_LEN
Maximum size of a client ID.
Definition: duid.h:128
const std::vector< uint8_t > & getClientId() const
Returns reference to the client-id data.
Definition: duid.cc:117
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Definition: duid.cc:122
Exchange Lease4 information between Kea and CQL.
static constexpr StatementTag GET_LEASE4_HWADDR_SUBID
static constexpr StatementTag GET_LEASE4_EXPIRE
void createBindForUpdate(const Lease4Ptr &lease, AnyArray &data, StatementTag statement_tag=NULL)
Create CQL_BIND objects for Lease4 Pointer.
static StatementMap tagged_statements_
Cassandra statements.
static constexpr StatementTag GET_LEASE4_PAGE
void getLeaseCollection(StatementTag &statement_tag, AnyArray &data, Lease4Collection &result)
Retrieves zero or more IPv4 leases.
static constexpr StatementTag GET_LEASE4_LIMIT
void createBindForInsert(const Lease4Ptr &lease, AnyArray &data)
Create CQL_BIND objects for Lease4 Pointer.
void getLease(StatementTag &statement_tag, AnyArray &data, Lease4Ptr &result)
Retrieves one IPv4 lease.
virtual void createBindForSelect(AnyArray &data, StatementTag statement_tag=NULL) override
Create BIND array to receive data.
static constexpr StatementTag INSERT_LEASE4
Statement tags definitions.
CqlLease4Exchange(const CqlConnection &connection)
Constructor.
static constexpr StatementTag GET_LEASE4_CLIENTID_SUBID
static constexpr StatementTag UPDATE_LEASE4
virtual boost::any retrieve() override
Retrieves the Lease4 object in Kea format.
static constexpr StatementTag DELETE_LEASE4
static constexpr StatementTag GET_LEASE4
void createBindForDelete(const Lease4Ptr &lease, AnyArray &data, StatementTag statement_tag=NULL)
Create CQL_BIND objects for Lease4 Pointer.
static constexpr StatementTag GET_LEASE4_ADDR
static constexpr StatementTag GET_LEASE4_SUBID
void getExpiredLeases(const size_t &max_leases, Lease4Collection &expired_leases)
Returns expired leases.
static constexpr StatementTag GET_LEASE4_CLIENTID
static constexpr StatementTag GET_LEASE4_HOSTNAME
static constexpr StatementTag GET_LEASE4_HWADDR
Exchange Lease6 information between Kea and CQL.
void createBindForDelete(const Lease6Ptr &lease, AnyArray &data, StatementTag statement_tag=NULL)
Create CQL_BIND objects for Lease4 Pointer.
static constexpr StatementTag DELETE_LEASE6
virtual boost::any retrieve() override
Retrieves the Lease6 object in Kea format.
static StatementMap tagged_statements_
Cassandra statements.
static constexpr StatementTag GET_LEASE6_DUID
static constexpr StatementTag UPDATE_LEASE6
void createBindForInsert(const Lease6Ptr &lease, AnyArray &data)
Create CQL_BIND objects for Lease6 Pointer.
void getLease(StatementTag &statement_tag, AnyArray &data, Lease6Ptr &result)
Retrieves one IPv6 lease.
static constexpr StatementTag GET_LEASE6_HOSTNAME
static constexpr StatementTag GET_LEASE6_PAGE
virtual void createBindForSelect(AnyArray &data, StatementTag statement_tag=NULL) override
Create BIND array to receive data.
void getExpiredLeases(const size_t &max_leases, Lease6Collection &expired_leases)
Returns expired leases.
static constexpr StatementTag INSERT_LEASE6
Statement tags definitions.
static constexpr StatementTag GET_LEASE6_EXPIRE
static constexpr StatementTag GET_LEASE6_DUID_IAID
static constexpr StatementTag GET_LEASE6_ADDR
void createBindForUpdate(const Lease6Ptr &lease, AnyArray &data, StatementTag statement_tag=NULL)
Create CQL_BIND objects for Lease6 Pointer.
void getLeaseCollection(StatementTag &statement_tag, AnyArray &data, Lease6Collection &result)
Retrieves zero or more IPv6 leases.
static constexpr StatementTag GET_LEASE6_LIMIT
CqlLease6Exchange(const CqlConnection &connection)
Constructor.
static constexpr StatementTag GET_LEASE6_DUID_IAID_SUBID
Common CQL and Lease Data Methods.
virtual void createBindForSelect(AnyArray &data, StatementTag statement_tag=NULL) override=0
Create BIND array to receive C++ data.
cass_bool_t fqdn_fwd_
Has forward DNS update been performed?
std::string user_context_
User context.
std::string hostname_
Client hostname.
cass_int64_t valid_lifetime_
Lease timer.
cass_int32_t subnet_id_
Subnet identifier.
cass_int32_t state_
Lease state.
cass_bool_t fqdn_rev_
Has reverse DNS update been performed?
cass_int64_t expire_
Lease expiry time.
virtual boost::any retrieve() override=0
Copy received data into the derived class' object.
cass_int64_t current_expire_
Expiration time of lease before update.
const CqlConnection & connection_
Database connection.
CqlLeaseExchange(const CqlConnection &connection)
Constructor.
CassBlob hwaddr_
Hardware address.
virtual size_t wipeLeases6(const SubnetID &subnet_id) override
Removed specified IPv6 leases.
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const override
Returns a collection of expired DHCPv4 leases.
virtual LeaseStatsQueryPtr startLeaseStatsQuery4() override
Creates and runs the IPv4 lease stats query.
virtual Lease6Collection getLeases6() const override
Returns all IPv6 leases.
virtual void updateLease6(const Lease6Ptr &lease6) override
Updates IPv6 lease.
virtual std::string getDescription() const override
Returns description of the backend.
bool deleteLease(const Lease4Ptr &lease) override final
Deletes an IPv4 lease.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const override
Basic lease access methods.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id) override
Creates and runs the IPv6 lease stats query for a single subnet.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id) override
Creates and runs the IPv4 lease stats query for a single subnet.
static std::string getDBVersion()
Local version of getDBVersion() class method.
virtual std::string getName() const override
Returns name of the database.
virtual size_t wipeLeases4(const SubnetID &subnet_id) override
Removes specified IPv4 leases.
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const override
Returns a collection of expired DHCPv6 leases.
virtual bool addLease(const Lease4Ptr &lease) override
Adds an IPv4 lease.
virtual Lease4Collection getLeases4() const override
Returns all IPv4 leases.
virtual VersionPair getVersion() const override
Returns backend version.
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id) override
Creates and runs the IPv4 lease stats query for a single subnet.
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs) override
Deletes all expired and reclaimed DHCPv4 leases.
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id) override
Creates and runs the IPv6 lease stats query for a single subnet.
virtual void rollback() override
Rollback Transactions.
virtual void updateLease4(const Lease4Ptr &lease4) override
Updates IPv4 lease.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs) override
Deletes all expired and reclaimed DHCPv6 leases.
CqlLeaseMgr(const db::DatabaseConnection::ParameterMap &parameters)
Constructor.
virtual ~CqlLeaseMgr()
Destructor (closes database)
virtual void commit() override
Commit Transactions.
virtual LeaseStatsQueryPtr startLeaseStatsQuery6() override
Creates and runs the IPv6 lease stats query.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const override
Returns existing IPv6 lease for a given IPv6 address.
Base CQL derivation of the statistical lease data query.
static constexpr StatementTag ALL_LEASE6_STATS
bool getNextRow(LeaseStatsRow &row)
Fetches the next row in the result set.
void executeSelect(const CqlConnection &connection, const AnyArray &data, StatementTag statement_tag)
Executes protocol specific lease query SELECT statement.
static StatementMap tagged_statements_
Cassandra statements.
static constexpr StatementTag SUBNET_LEASE4_STATS
Return lease4 lease statistics for a single subnet.
static constexpr StatementTag ALL_LEASE4_STATS
Statement tags definitions.
static constexpr StatementTag SUBNET_LEASE6_STATS
Return lease6 lease statistics for a single subnet.
static constexpr StatementTag SUBNET_RANGE_LEASE6_STATS
Return lease6 lease statistics for a range of subnets.
void start()
Creates the lease statistical data result set.
virtual ~CqlLeaseStatsQuery()
Destructor.
virtual void createBindForSelect(AnyArray &data, StatementTag statement_tag=NULL)
Create BIND array to receive C++ data.
CqlLeaseStatsQuery(CqlConnection &conn, StatementTag &statement, const bool fetch_type, const SubnetID &subnet_id)
Constructor to query for a single subnet's stats.
static constexpr StatementTag SUBNET_RANGE_LEASE4_STATS
Return lease4 lease statistics for a range of subnets.
CqlLeaseStatsQuery(CqlConnection &conn, StatementTag &statement, const bool fetch_type, const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Constructor to query for the stats for a range of subnets.
CqlLeaseStatsQuery(CqlConnection &conn, StatementTag &statement, const bool fetch_type)
Constructor to query for all subnets' stats.
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:27
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Definition: duid.cc:75
static const size_t MAX_DUID_LEN
maximum duid size As defined in RFC 8415, section 11.1
Definition: duid.h:31
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
Definition: duid.cc:46
Wraps value holding size of the page with leases.
Definition: lease_mgr.h:43
const size_t page_size_
Holds page size.
Definition: lease_mgr.h:53
Base class for fulfilling a statistical lease data query.
Definition: lease_mgr.h:128
SubnetID first_subnet_id_
First (or only) subnet_id in the selection criteria.
Definition: lease_mgr.h:192
SelectMode getSelectMode() const
Returns the selection criteria mode The value returned is based upon the constructor variant used and...
Definition: lease_mgr.h:190
SubnetID last_subnet_id_
Last subnet_id in the selection criteria when a range is given.
Definition: lease_mgr.h:199
Attempt to update lease that was not there.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
char const *const StatementTag
Statement index representing the statement name.
std::pair< uint32_t, uint32_t > VersionPair
Pair containing major and minor versions.
@ error
Definition: db_log.h:118
std::vector< cass_byte_t > CassBlob
Host identifier converted to Cassandra data type.
Definition: cql_exchange.h:37
constexpr uint32_t CQL_SCHEMA_VERSION_MINOR
constexpr uint32_t CQL_SCHEMA_VERSION_MAJOR
Define CQL schema version: 5.0.
std::unordered_map< StatementTag, CqlTaggedStatement, StatementTagHash, StatementTagEqual > StatementMap
A container for all statements.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
const isc::log::MessageID DHCPSRV_CQL_UPDATE_ADDR4
const isc::log::MessageID DHCPSRV_CQL_GET_ADDR4
const isc::log::MessageID DHCPSRV_CQL_GET_SUBID_HWADDR
const isc::log::MessageID DHCPSRV_CQL_GET_SUBID_CLIENTID
const isc::log::MessageID DHCPSRV_CQL_GET_SUBID4
const isc::log::MessageID DHCPSRV_CQL_GET_HOSTNAME4
const isc::log::MessageID DHCPSRV_CQL_DELETE_EXPIRED_RECLAIMED6
const isc::log::MessageID DHCPSRV_CQL_GET_HWADDR
const isc::log::MessageID DHCPSRV_CQL_ADD_ADDR4
const isc::log::MessageID DHCPSRV_CQL_GET_VERSION
const isc::log::MessageID DHCPSRV_CQL_GET_EXPIRED4
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:20
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:492
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition: lease.h:640
boost::shared_ptr< LeaseStatsQuery > LeaseStatsQueryPtr
Defines a pointer to a LeaseStatsQuery.
Definition: lease_mgr.h:207
const isc::log::MessageID DHCPSRV_CQL_COMMIT
const isc::log::MessageID DHCPSRV_CQL_GET4
const isc::log::MessageID DHCPSRV_CQL_GET_CLIENTID
const isc::log::MessageID DHCPSRV_CQL_GET_ADDR6
const isc::log::MessageID DHCPSRV_CQL_ROLLBACK
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Definition: dhcpsrv_log.h:38
const isc::log::MessageID DHCPSRV_CQL_UPDATE_ADDR6
const isc::log::MessageID DHCPSRV_CQL_DELETE_EXPIRED_RECLAIMED4
const isc::log::MessageID DHCPSRV_CQL_LEASE_EXCEPTION_THROWN
const isc::log::MessageID DHCPSRV_CQL_GET_IAID_DUID
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
Definition: lease.h:24
const isc::log::MessageID DHCPSRV_CQL_GET_EXPIRED6
const isc::log::MessageID DHCPSRV_DEPRECATED
const isc::log::MessageID DHCPSRV_CQL_ADD_ADDR6
const isc::log::MessageID DHCPSRV_CQL_GET_IAID_SUBID_DUID
const isc::log::MessageID DHCPSRV_CQL_GET_HOSTNAME6
const isc::log::MessageID DHCPSRV_CQL_GET_PAGE4
const isc::log::MessageID DHCPSRV_CQL_DELETE_ADDR
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
Definition: lease.h:487
@ HTYPE_ETHER
Ethernet 10Mbps.
Definition: dhcp4.h:56
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition: lease.h:283
const isc::log::MessageID DHCPSRV_CQL_GET_PAGE6
Defines the logger used by the top-level component of kea-lfc.
Defines a single statement or query.
StatementTag name_
Short description of the query.
bool is_raw_
Should the statement be executed raw or with binds?
const CassPrepared * prepared_statement_
Internal Cassandra object representing the prepared statement.
Hardware type that represents information from DHCPv4 packet.
Definition: hwaddr.h:20
static const size_t MAX_HWADDR_LEN
Maximum size of a hardware address.
Definition: hwaddr.h:27
std::vector< uint8_t > hwaddr_
Definition: hwaddr.h:98
std::string toText(bool include_htype=true) const
Returns textual representation of a hardware address (e.g.
Definition: hwaddr.cc:51
Contains a single row of lease statistical data.
Definition: lease_mgr.h:61
int64_t state_count_
state_count The count of leases in the lease state
Definition: lease_mgr.h:120
uint32_t lease_state_
The lease_state to which the count applies.
Definition: lease_mgr.h:118
SubnetID subnet_id_
The subnet ID to which this data applies.
Definition: lease_mgr.h:114
Lease::Type lease_type_
The lease_type to which the count applies.
Definition: lease_mgr.h:116
static const uint32_t STATE_DEFAULT
A lease in the default state.
Definition: lease.h:73
static const uint32_t STATE_DECLINED
Declined lease.
Definition: lease.h:76
static const uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
Definition: lease.h:79
Type
Type of lease or pool.
Definition: lease.h:50
@ TYPE_TA
the lease contains temporary IPv6 address
Definition: lease.h:52
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition: lease.h:53
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition: lease.h:51