MySQL 9.0.0
Source Code Documentation
operations.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef OPERATIONS_INCLUDED
25#define OPERATIONS_INCLUDED
26
27#include <memory> /* std::unique_ptr */
28
33
34/* clang-format off */
35/**
36 @page PAGE_COMPONENT_KEYRING_COMMON Common Keyring Implementation Infrastructure
37
38 keyring_common library includes modules that can be used in various keyring
39 implementation. This library provides implementation of following:
40
41 1. A JSON configuration file reader and parser
42 2. A data reader/writer using JSON as format
43 3. A backup file based file reader/writer
44 4. Sensitive data container
45 5. Metadata - Used to uniquely identify sensitive data
46 6. A wrapper to define extension over sensitive data
47 E.g. ID as provided by key management server
48 7. An in-memory cache to store Metadata OR {Metadata, Data}
49 8. An iterator over cache
50 9. Operations class to interface services APIs with implementation
51 10. AES encryption/decryption operations
52 11. Set of utility functions such as random data generator, hex converter etc.
53
54 Following diagram shows interactions between various parts of keyring_common
55 library and how they can be used to implement a keyring component.
56
57 The diagram uses a file based backend as example and how it can use
58 various modules provided by keyring_common library.
59
60 @startuml
61 package Error_logging {
62 object LogErr
63
64 LogErr -[#red]-> Service_implementation_templates
65 LogErr -[#red]-> Component_implementation
66 }
67
68 package Component_implementation {
69 object Service_implementation
70 object Backend
71 object Component_specific_constraints
72
73 Service_implementation <-[#red]- Backend
74 Backend <.[#red]. Json_data
75 Backend <.[#red]. Backup_aware_file_ops
76 Service_implementation -[#red]-> Operations
77 Backend <.[#red]. Encryption
78 Service_implementation <-[#red]- Config_reader
79 Component_specific_constraints -[#red]-> Service_implementation_templates
80 Service_implementation <-[#red]- service_definition_headers
81
82 Component_specific_constraints -[hidden]left- LogErr
83 }
84
85 package Library_mysys {
86 object Hex_tools
87
88 Backend -[hidden]right- Hex_tools
89 }
90
91 package Keyring_common {
92 package service_definition_headers {
93 object Writer_definition
94 object Load_definition
95 object Reader_definition
96 object Metadata_query_definition
97 object Keys_metadata_iterator_definition
98 object Generator_definition
99 object Encryption_definition
100
101 Load_definition -[hidden]up- Writer_definition
102 Writer_definition -[hidden]up- Reader_definition
103 Reader_definition -[hidden]up- Metadata_query_definition
104 Metadata_query_definition -[hidden]up- Keys_metadata_iterator_definition
105 Keys_metadata_iterator_definition -[hidden]up- Generator_definition
106 Generator_definition -[hidden]up- Encryption_definition
107 }
108
109 package Config_reader {
110 object Json_config_reader
111 }
112
113 package Backup_aware_file_ops {
114 object File_writer
115 object File_reader
116
117 File_reader <-[#red]left- File_writer
118 }
119
120 package Json_data {
121 object Json_writer
122 object Json_reader
123
124 Hex_tools -[#red]-> Json_reader
125 Hex_tools -[#red]-> Json_writer
126 }
127
128 package Data_representation {
129 object Data
130 object Metadata
131 }
132
133 package Memstore {
134 object Iterator
135 object Cache
136
137 Cache <-[#red]- Data_representation
138 Cache <-[#red]- Iterator
139 }
140
141 package Operations {
142 object Operation_manager
143
144 Operation_manager <-[#red]- Memstore
145 Operation_manager -[#red]-> Service_implementation_templates
146 }
147
148 package Utils {
149 object PRNG
150 }
151
152 package Encryption {
153 object AES
154 }
155
156 PRNG -[hidden]up- AES
157
158 package Internal_error_logging {
159 object Internal_LogErr
160
161 Internal_LogErr .[#red].> LogErr
162 }
163
164 package Service_implementation_templates {
165 object Writer_template
166 object Reader_template
167 object Metadata_query_template
168 object Keys_metadata_iterator_template
169 object Generator_template
170 object Encryption_template
171
172 Writer_template -[hidden]up- Reader_template
173 Reader_template -[hidden]up- Metadata_query_template
174 Metadata_query_template -[hidden]up- Keys_metadata_iterator_template
175 Keys_metadata_iterator_template -[hidden]up- Generator_template
176 Generator_template -[hidden]up- Encryption_template
177
178 Encryption -[#red]right-> Encryption_template
179 PRNG -[#red]-> Generator_template
180 }
181
182 Service_implementation -[hidden]down- Operations
183 }
184 @enduml
185*/
186
187/**
188 @page PAGE_COMPONENT_KEYRING_WRITE_NEW "How to write a new keyring component"
189
190 Common keyring implementation infrastructure provides useful parts to minimize
191 efforts involved in writing a new component. This page will provide details about
192 how a new keyring component can be implemented using the common infrastructure
193
194 Any keyring component can be divided in 3 parts:
195
196 1. Configuration Management
197 1. Service Implementation
198 3. Backend Management
199
200 @section configuration_management Configuration Management
201 A binary must be able to load a keyring component on top of minimal chassis.
202 Hence, the component cannot use option management provided by underlying binary
203 to read configuration for the keyring.
204
205 One way to read configuration is to accept it as a JSON file.
206 A sample configuration file may look like following:
207 @code
208 {
209 "version" : "1.0.0"
210 "config_key_1" : "config_data_1",
211 "config_key_2" : "config_data_2",
212 "config_key_3" : "config_data_3"
213 }
214 @endcode
215
216 Various (key, value) pair would help component get details required
217 to communicate with backend and initialize keyring.
218
219 You can use @ref keyring_common::config::Config_reader
220 to read a JSON file and extract value of individual configuration parameters.
221
222 Depending upon the services implemented by the component, it is possible that:
223
224 A> Configuration data can be queried at runtime
225
226 B> Configuration can be changed at runtime
227
228 @section service_implementation Service Implementation
229 Please refer to @ref PAGE_KEYRING_COMPONENT for description of various services
230 that a keyring component should implement. You may take a look at
231 @ref group_keyring_component_services_inventory for details about specific services
232 and various APIs.
233
234 If you are writing a keyring component that should work with MySQL server,
235 the component must implement following services.
236 1. Keyring reader service: @ref s_mysql_keyring_reader_with_status
237 Use @ref keyring_common::service_definition::Keyring_reader_service_impl
238 for service class declaration.
239 Use @ref KEYRING_READER_IMPLEMENTOR to add service implementation details
240 required by component infrastructure.
241 2. Keyring writer service: @ref s_mysql_keyring_writer
242 Use @ref keyring_common::service_definition::Keyring_writer_service_impl
243 for service class declaration.
244 Use @ref KEYRING_WRITER_IMPLEMENTOR to add service implementation details
245 required by component infrastructure.
246 3. Keyring generator service: @ref s_mysql_keyring_generator
247 Use @ref keyring_common::service_definition::Keyring_generator_service_impl
248 for service class declaration.
249 Use @ref KEYRING_GENERATOR_IMPLEMENTOR to add service implementation details
250 required by component infrastructure.
251 4. Keyring keys metadata iterator service: @ref s_mysql_keyring_keys_metadata_iterator
252 Use @ref keyring_common::service_definition::Keyring_keys_metadata_iterator_service_impl
253 for service class declaration.
254 Use @ref KEYRING_KEYS_METADATA_FORWARD_ITERATOR_IMPLEMENTOR to add service implementation details
255 required by component infrastructure.
256 5. Keyring component metadata query service: @ref s_mysql_keyring_component_metadata_query
257 Use @ref keyring_common::service_definition::Keyring_metadata_query_service_impl
258 for service class declaration.
259 Use @ref KEYRING_COMPONENT_METADATA_QUERY_IMPLEMENTOR to add service implementation details
260 required by component infrastructure.
261 6. Keyring load service: @ref s_mysql_keyring_load
262 Use @ref keyring_common::service_definition::Keyring_load_service_impl
263 for service class declaration.
264 Use @ref KEYRING_LOAD_IMPLEMENTOR to add service implementation details
265 required by component infrastructure.
266 7. Keyring AES service: @ref s_mysql_keyring_aes
267 Use @ref keyring_common::service_definition::Keyring_aes_service_impl
268 for service class declaration.
269 Use @ref KEYRING_AES_IMPLEMENTOR to add service implementation details
270 required by component infrastructure.
271 8. Keyring status service: @ref s_mysql_keyring_component_status
272 Use @ref keyring_common::service_definition::Keyring_metadata_query_service_impl
273 for service class declaration.
274 Use @ref KEYRING_COMPONENT_STATUS_IMPLEMENTOR to add service implementation details
275 required by component infrastructure.
276
277 Please note that key of type AES and SECRET must be supported.
278
279 In addition, you will also need to implement log_builtins and log_builtins_string
280 services if you are planning to use keyring common's implementation templates.
281 The common keyring infrastrcture has a bare-minimum implementation of these
282 services. You can use @ref keyring_common::service_definition::Log_builtins_keyring
283 for service class declaration. Use @ref KEYRING_LOG_BUILTINS_IMPLEMENTOR and
284 @ref KEYRING_LOG_BUILTINS_STRING_IMPLEMENTOR to add service implementation details
285 required by component infrastrcture.
286
287 Common keyring infrastructure also provides implementation for some of the above
288 mentioned services. This will allow implementor to create a minimal definition of
289 service APIs and use templates provided by common infra.
290
291 In order to do that, common keyring infrastrcture requires following:
292
293 1. A handle to @ref keyring_common::operations::Keyring_operations object
294 This class provides a wrapper over keyring backend and expect that implementor provides
295 handle to a backend class with set of APIs required to manage keys. Please see
296 @ref backend_management for more details.
297 2. A handle to @ref keyring_common::service_implementation::Component_callbacks object
298 This class provides callback methods which are implemented by individual component.
299 For example: Keyring state, Maximum supported data length, metadata vector creation etc.
300
301 Assumping that above mentioned dependencies are satisfied, following are some inputs
302 on how various services can be implemented.
303 1. Keyring reader service: @ref s_mysql_keyring_reader_with_status
304 See @ref keyring_common::service_implementation::init_reader_template
305 See @ref keyring_common::service_implementation::deinit_reader_template
306 See @ref keyring_common::service_implementation::fetch_length_template
307 See @ref keyring_common::service_implementation::fetch_template
308 2. Keyring writer service: @ref s_mysql_keyring_writer
309 See @ref keyring_common::service_implementation::store_template
310 See @ref keyring_common::service_implementation::remove_template
311 3. Keyring generator service: @ref s_mysql_keyring_generator
312 See @ref keyring_common::service_implementation::generate_template
313 4. Keyring keys metadata iterator service: @ref s_mysql_keyring_keys_metadata_iterator
314 See @ref keyring_common::service_implementation::init_keys_metadata_iterator_template
315 See @ref keyring_common::service_implementation::deinit_keys_metadata_iterator_template
316 See @ref keyring_common::service_implementation::keys_metadata_iterator_is_valid
317 See @ref keyring_common::service_implementation::keys_metadata_iterator_next
318 See @ref keyring_common::service_implementation::keys_metadata_get_length_template
319 See @ref keyring_common::service_implementation::keys_metadata_get_template
320 5. Keyring component metadata query service: @ref s_mysql_keyring_component_metadata_query
321 See @ref keyring_common::service_implementation::keyring_metadata_query_init_template
322 See @ref keyring_common::service_implementation::keyring_metadata_query_deinit_template
323 See @ref keyring_common::service_implementation::keyring_metadata_query_is_valid_template
324 See @ref keyring_common::service_implementation::keyring_metadata_query_next_template
325 See @ref keyring_common::service_implementation::keyring_metadata_query_get_length_template
326 See @ref keyring_common::service_implementation::keyring_metadata_query_get_template
327 6. Keyring load service: @ref s_mysql_keyring_load
328 This service is specific to individual keyring component because it has strong
329 dependency on component specific configuration details. The component should implement
330 it as per its own requirement.
331 7. Keyring AES service: @ref s_mysql_keyring_aes
332 See @ref keyring_common::service_implementation::aes_get_encrypted_size_template
333 See @ref keyring_common::service_implementation::aes_encrypt_template
334 See @ref keyring_common::service_implementation::aes_decrypt_template
335 8. Keyring status service: @ref s_mysql_keyring_component_status
336 See @ref keyring_common::service_implementation::keyring_metadata_query_keyring_initialized_template
337
338 @section backend_management Backend Management
339 This part would be different for each keyring component. Backend can be a remote server,
340 something that stored locally or a combination of both. Regardless of the backend, if
341 @ref keyring_common::operations::Keyring_operations is to be used, component must implement
342 a class similar to following:
343
344 @code
345 template <typename Data_extension>
346 class Backend {
347 public:
348 // Fetch data
349
350 // @param [in] metadata Key
351 // @param [out] data Value
352
353 // @returns Status of find operation
354 // @retval false Entry found. Check data.
355 // @retval true Entry missing.
356 bool get(const keyring_common::meta::Metadata &metadata,
357 keyring_common::data::Data &data) const;
358
359 // Store data
360
361 // @param [in] metadata Key
362 // @param [in, out] data Value
363
364 // @returns Status of store operation
365 // @retval false Entry stored successfully
366 // @retval true Failure
367 bool store(const keyring_common::meta::Metadata &metadata,
368 keyring_common::data::Data &data);
369
370 // Erase data located at given key
371
372 // @param [in] metadata Key
373 // @param [in] data Value - not used.
374
375 // @returns Status of erase operation
376 // @retval false Data deleted
377 // @retval true Could not find or delete data
378 bool erase(const keyring_common::meta::Metadata &metadata,
379 keyring_common::data::Data &data);
380
381 // Generate random data and store it
382
383 // @param [in] metadata Key
384 // @param [out] data Generated value
385 // @param [in] length Length of data to be generated
386
387 // @returns Status of generate + store operation
388 // @retval false Data generated and stored successfully
389 // @retval true Error
390 bool generate(const keyring_common::meta::Metadata &metadata,
391 keyring_common::data::Data &data, size_t length);
392
393 // Populate cache
394
395 // @param [in] operations Handle to operations class
396
397 // @returns status of cache insertion
398 // @retval false Success
399 // @retval true Failure
400 bool load_cache(
401 keyring_common::operations::Keyring_operations<Keyring_file_backend>
402 &operations);
403
404 // Maximum data length supported
405 size_t maximum_data_length() const;
406
407 // Get number of elements stored in backend
408 size_t size() const;
409 };
410 @endcode
411
412 Common keyring infrastructure includes implementation that may help file management.
413 It provides a content agnostic, backup aware file reader and writer.
414
415 Writer works in following manner:
416 - Write content to backup file
417 - If backup file exists, copy its content to main file
418 - Remove backup file
419
420 Reader works in following manner:
421 - Invoke writer to process backup file, if it exists
422 - Read from main file
423
424 Please see @ref keyring_common::data_file::File_writer for writer details and
425 @ref keyring_common::data_file::File_reader for reader details.
426
427 @section in_member_data_management In-memory Data Management
428
429 Common keyring infrastructure also provides useful classes to manage data in memory.
430
431 1. To cache metadata related to data, use @ref keyring_common::meta::Metadata
432 2. To cache data in memory, use @ref keyring_common::data::Data
433 3. To cache backend specific details for data (e.g. ID generated by backend),
434 use @ref keyring_common::data::Data_extension
435 4. A reader/writer pair for JSON data that can be used to store data, related metadata
436 and data extension if any. See @ref keyring_common::json_data::Json_reader
437 and @ref keyring_common::json_data::Json_writer.
438
439 Expected JSON format is specified below:
440
441 @code
442
443 {
444 "version": "1.0",
445 "elements": [
446 {
447 "user": "<user_name>",
448 "data_id": "<name>",
449 "data_type": "<data_type>",
450 "data": "<hex_of_data>",
451 "extension": [
452 ]
453 },
454 ...
455 ...
456 ]
457 }
458
459 @endcode
460*/
461
462/* clang-format on */
463
465
466/**
467 Keyring operations
468 A class to perform operations on keyring.
469 If cache is enabled, operations uses it. Otherwise,
470 backend is used.
471
472 Assumptions:
473 1. Backend implements interface to keyring backend.
474 2. Backend is required to support same Data_extension as Keyring_operations
475
476 Please see @ref PAGE_COMPONENT_KEYRING_WRITE_NEW for details about
477 Backend class.
478*/
479
480template <typename Backend, typename Data_extension = data::Data>
482 public:
483 /**
484 Constructor
485
486 @param [in] cache_data Whether to cache data or not
487 @param [in] backend Pointer to keyring backend
488
489 Populates the cache from backend
490 */
491 explicit Keyring_operations(bool cache_data, Backend *backend)
492 : cache_(), cache_data_(cache_data), backend_(backend), valid_(false) {
493 load_cache();
494 }
495
497
498 /**
499 Insert API to populate cache
500
501 @param [in] metadata Key to the data
502 @param [in] secret_data Actual data
503
504 @returns status of insertion
505 @retval false Success
506 @retval true Failure
507 */
508 bool insert(const meta::Metadata &metadata, Data_extension secret_data) {
509 /* valid_ = true implies cache is operational. Do not permit bulk insert */
510 if (valid_) return true;
511 if (!cache_data_) secret_data.set_data(data::Data{});
512 return !cache_.store(metadata, secret_data);
513 }
514
515 public:
516 /**
517 Search API
518
519 @param [in] metadata Key to the data
520 @param [out] data Fetched data
521
522 @returns status of search operation
523 @retval false Success - data contains required information
524 @retval true Failure - data is not valid
525 */
526 bool get(const meta::Metadata &metadata, data::Data &data) {
527 Data_extension fetched_data;
528 if (!metadata.valid()) return true;
529 if (!cache_.get(metadata, fetched_data)) return true;
530 if (!cache_data_) {
531 /* Fetch data from backend */
532 if ((*backend_).get(metadata, fetched_data)) return true;
533 }
534 data = fetched_data.get_data();
535 return false;
536 }
537
538 /**
539 Get Backend-specific data extension
540
541 @param [in] metadata Key to the data
542 @param [out] data Fetched data extension
543
544 @returns status of search operation
545 @retval false Success - data contains required information
546 @retval true Failure - data is not valid
547
548 NOTE: get_data_extension NEVER returns data.
549 It only returns Data extension information.
550 */
551 bool get_data_extension(const meta::Metadata &metadata,
552 Data_extension &data) {
553 if (!metadata.valid()) return true;
554 if (!cache_.get(metadata, data)) return true;
555 if (cache_data_) data.set_data(data::Data{});
556 return false;
557 }
558
559 /**
560 Store API
561
562 @param [in] metadata Key to the data
563 @param [in] data Data to be stored
564
565 @returns status of store operation
566 @retval false Success - data stored
567 @retval true Failure
568 */
569 bool store(const meta::Metadata &metadata, const data::Data &data) {
570 Data_extension stored_data(data);
571 if (!metadata.valid()) return true;
572 Data_extension fetched_data;
573 if (cache_.get(metadata, fetched_data)) return true;
574 if ((*backend_).store(metadata, stored_data)) return true;
575 /*
576 Note: We always cache metadata.
577 So we always consult the operation's cache first
578 to see if valid (data_id, auth_id) pair exists.
579
580 This would also retrieve backend specific metadata
581 if any.
582
583 Once we confirm that key is present, we then fetch
584 the data either from the cache(if caching is ON)
585 or from the backend(if caching is OFF).
586 */
587 if (!cache_data_) {
588 /* Just store the metadata */
589 stored_data.set_data(data::Data{});
590 }
591 if (!cache_.store(metadata, stored_data)) {
592 /* Failed caching the data. Remove it from backend too. */
593 (void)(*backend_).erase(metadata, stored_data);
594 return true;
595 }
596 return false;
597 }
598
599 /**
600 Remove API
601
602 @param [in] metadata Key to the data
603
604 @returns status of remove operation
605 @retval false Success - data removed OR does not exist
606 @retval true Failure
607 */
608 bool erase(const meta::Metadata &metadata) {
609 if (!metadata.valid()) return true;
610 Data_extension fetched_data;
611 /* Get backend specific extension from cache */
612 if (!cache_.get(metadata, fetched_data)) return true;
613 /* Remove it from backend */
614 if ((*backend_).erase(metadata, fetched_data)) return true;
615 /* Remove it from the cache */
616 cache_.erase(metadata);
617 return false;
618 }
619
620 /**
621 Generate API
622
623 @param [in] metadata Key for the data
624 @param [in] type Type of data
625 @param [in] length Length of data to be generated
626
627 @returns status of data generation
628 @retval false Success - data generated and stored in backend
629 @retval true Failure
630 */
631 bool generate(const meta::Metadata &metadata, const data::Type type,
632 size_t length) {
633 if (!metadata.valid()) return true;
634 data::Data g_data(type);
635 Data_extension generated_data(g_data);
636 if (cache_.get(metadata, generated_data)) return true;
637 if ((*backend_).generate(metadata, generated_data, length)) return true;
638 if (!cache_data_) generated_data.set_data(data::Data{});
639 if (!cache_.store(metadata, generated_data)) {
640 /* Failed to cache the data, remove it from backend too */
641 (void)(*backend_).erase(metadata, generated_data);
642 return true;
643 }
644 return false;
645 }
646
647 /**
648 Iterator creation for read
649
650 If data is cached, iterator on cached data is returned.
651 Otherwise iterator created by backend is returned.
652
653 @param [out] it Forward iterator to metadata
654 @param [in] metadata Metadata for the record to be searched
655
656 @returns Status
657 @retval false Success
658 @retval true Failure
659 */
662 const meta::Metadata &metadata) {
663 if (!valid()) return true;
664 if (!metadata.valid()) return true;
665 it = std::make_unique<iterator::Iterator<Data_extension>>(cache_, metadata);
666 return (it.get() == nullptr);
667 }
668
669 /**
670 Iterator creation
671
672 @param [out] it Forward iterator to metadata
673 @param [in] cached Iterator type
674
675 @returns Status
676 @retval false Success
677 @retval true Failure
678 */
681 if (!valid()) return true;
682 it = std::make_unique<iterator::Iterator<Data_extension>>(cache_, cached);
683 return (it.get() == nullptr);
684 }
685
686 /**
687 Iterator destruction
688
689 @param [in, out] it Forward iterator to metadata
690
691 */
694 it.reset(nullptr);
695 }
696
697 /**
698 Check iterator validity
699
700 @param [in] it Forward iterator to metadata
701
702 @returns Status
703 @retval true Valid
704 @retval false Invalid
705 */
707 return (valid() && it.get() != nullptr && (*it).valid(cache_.version()));
708 }
709
710 /**
711 Move iterator forward
712
713 @param [in] it Forward iterator to metadata
714
715 @returns Status
716 @retval false Success
717 @retval true Failure
718 */
720 if (valid() && it.get() != nullptr) return !((*it).next(cache_.version()));
721 return true;
722 }
723
724 /**
725 Get data from iterator
726
727 @param [in] it Forward iterator to metadata
728 @param [out] metadata Metadata for given key
729 @param [out] data Data for given key (Including extension)
730
731 @returns Status
732 @retval false Success
733 @retval true Failure
734 */
737 meta::Metadata &metadata, Data_extension &data) {
738 if (!valid() || it.get() == nullptr || !(*it).valid(cache_.version()))
739 return true;
740 if (!(*it).metadata(cache_.version(), metadata)) return true;
741 if (cache_data_) {
742 if (!(*it).data(cache_.version(), data)) return true;
743 } else {
744 cache_.get(metadata, data);
745 if ((*backend_).get(metadata, data)) return true;
746 }
747 return !metadata.valid();
748 }
749
750 /**
751 Get metadata from iterator
752
753 @param [in] it Forward iterator to metadata
754 @param [out] metadata Metadata for given key
755 @param [out] data Extension for given key
756
757 @returns Status
758 @retval false Success
759 @retval true Failure
760 */
763 meta::Metadata &metadata, Data_extension &data) {
764 if (!valid() || it.get() == nullptr || !(*it).valid(cache_.version()))
765 return true;
766 if (!(*it).metadata(cache_.version(), metadata)) return true;
767 if (!(*it).data(cache_.version(), data)) return true;
768 if (cache_data_) data.set_data(data::Data{});
769 return !metadata.valid();
770 }
771
772 /**
773 Maximum data length supported
774
775 @returns Maximum length supported
776 */
777 size_t maximum_data_length() const {
778 return (*backend_).maximum_data_length();
779 }
780
781 /** Keyring size */
782 size_t keyring_size() { return cache_.size(); }
783
784 /** Validity */
785 bool valid() { return valid_; }
786
787 private:
788 void load_cache() {
789 Backend *backend = backend_.get();
790 /* Clear the cache */
791 cache_.clear();
792
793 valid_ = false;
794 if (backend == nullptr || backend->size() == 0) {
795 valid_ = true;
796 return;
797 }
798
799 if (backend->load_cache(*this)) return;
800
801 /*
802 If we fail to load metadata (and data) for all keys,
803 wipe the cache clean.
804 */
805 if (backend->size() != cache_.size()) {
806 cache_.clear();
807 } else {
808 valid_ = true;
809 }
810 }
811
812 /** Metadata cache */
814 /** Flag to cache data */
816 /** Keyring backend */
817 std::unique_ptr<Backend> backend_;
818 /** Validity */
819 bool valid_;
820};
821
822} // namespace keyring_common::operations
823
824#endif // !OPERATIONS_INCLUDED
Definition: cache.h:39
Sensitive data storage.
Definition: data.h:39
virtual Data get_data() const
Return self.
Definition: data.cc:65
Definition: iterator.h:32
Common metadata.
Definition: meta.h:38
bool valid() const
Validity of metadata object.
Definition: meta.cc:75
Keyring operations A class to perform operations on keyring.
Definition: operations.h:481
bool erase(const meta::Metadata &metadata)
Remove API.
Definition: operations.h:608
bool next(std::unique_ptr< iterator::Iterator< Data_extension > > &it)
Move iterator forward.
Definition: operations.h:719
bool generate(const meta::Metadata &metadata, const data::Type type, size_t length)
Generate API.
Definition: operations.h:631
Keyring_operations(bool cache_data, Backend *backend)
Constructor.
Definition: operations.h:491
bool get_data_extension(const meta::Metadata &metadata, Data_extension &data)
Get Backend-specific data extension.
Definition: operations.h:551
bool store(const meta::Metadata &metadata, const data::Data &data)
Store API.
Definition: operations.h:569
bool get_iterator_data(std::unique_ptr< iterator::Iterator< Data_extension > > &it, meta::Metadata &metadata, Data_extension &data)
Get data from iterator.
Definition: operations.h:735
size_t maximum_data_length() const
Maximum data length supported.
Definition: operations.h:777
bool init_forward_iterator(std::unique_ptr< iterator::Iterator< Data_extension > > &it, bool cached)
Iterator creation.
Definition: operations.h:679
bool cache_data_
Flag to cache data.
Definition: operations.h:815
void deinit_forward_iterator(std::unique_ptr< iterator::Iterator< Data_extension > > &it)
Iterator destruction.
Definition: operations.h:692
bool valid()
Validity.
Definition: operations.h:785
bool insert(const meta::Metadata &metadata, Data_extension secret_data)
Insert API to populate cache.
Definition: operations.h:508
bool is_valid(std::unique_ptr< iterator::Iterator< Data_extension > > &it)
Check iterator validity.
Definition: operations.h:706
void load_cache()
Definition: operations.h:788
bool init_read_iterator(std::unique_ptr< iterator::Iterator< Data_extension > > &it, const meta::Metadata &metadata)
Iterator creation for read.
Definition: operations.h:660
cache::Datacache< Data_extension > cache_
Metadata cache.
Definition: operations.h:813
std::unique_ptr< Backend > backend_
Keyring backend.
Definition: operations.h:817
size_t keyring_size()
Keyring size.
Definition: operations.h:782
bool get_iterator_metadata(std::unique_ptr< iterator::Iterator< Data_extension > > &it, meta::Metadata &metadata, Data_extension &data)
Get metadata from iterator.
Definition: operations.h:761
bool get(const meta::Metadata &metadata, data::Data &data)
Search API.
Definition: operations.h:526
bool valid_
Validity.
Definition: operations.h:819
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
std::string Type
Data types.
Definition: data.h:32
Definition: operations.h:464
std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Array_deleter< std::remove_extent_t< T > > >, void > > unique_ptr
The following is a common type that is returned by all the ut::make_unique (non-aligned) specializati...
Definition: ut0new.h:2439
required string type
Definition: replication_group_member_actions.proto:34
static double cached
Definition: xcom_statistics.cc:101