1
+ /*
2
+ * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES
3
+ * Copyright (c) 2001-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4
+ * SPDX-License-Identifier: GPL-2.0-only or BSD-3-Clause
5
+ *
6
+ * This software is available to you under a choice of one of two
7
+ * licenses. You may choose to be licensed under the terms of the GNU
8
+ * General Public License (GPL) Version 2, available from the file
9
+ * COPYING in the main directory of this source tree, or the
10
+ * BSD license below:
11
+ *
12
+ * Redistribution and use in source and binary forms, with or
13
+ * without modification, are permitted provided that the following
14
+ * conditions are met:
15
+ *
16
+ * - Redistributions of source code must retain the above
17
+ * copyright notice, this list of conditions and the following
18
+ * disclaimer.
19
+ *
20
+ * - Redistributions in binary form must reproduce the above
21
+ * copyright notice, this list of conditions and the following
22
+ * disclaimer in the documentation and/or other materials
23
+ * provided with the distribution.
24
+ *
25
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
+ * SOFTWARE.
33
+ */
34
+
35
+ #include " config_manager.h"
36
+ #include " loaders/inline_loader.h"
37
+ #include " loaders/json_loader.h"
38
+ #include " descriptor_providers/json_descriptor_provider.h"
39
+ #include " core/util/xlio_exception.h"
40
+
41
+ #include < fstream>
42
+
43
+ config_manager::config_manager ()
44
+ {
45
+ std::queue<std::unique_ptr<loader>> loaders;
46
+
47
+ const char *inline_env = std::getenv (" XLIO_INLINE_CONFIG" );
48
+ if (inline_env) {
49
+ loaders.push (std::make_unique<inline_loader>(" XLIO_INLINE_CONFIG" ));
50
+ }
51
+
52
+ const char *custom_path = std::getenv (" XLIO_CUSTOM_CONFIG_FILE" );
53
+ if (custom_path) {
54
+ loaders.push (std::make_unique<json_loader>(custom_path));
55
+ } else {
56
+ loaders.push (std::make_unique<json_loader>(" /etc/libxlio_config.json" ));
57
+ }
58
+
59
+ initialize_manager (std::move (loaders), std::make_unique<json_descriptor_provider>());
60
+ }
61
+
62
+ void config_manager::initialize_manager (std::queue<std::unique_ptr<loader>> &&value_loaders,
63
+ std::unique_ptr<descriptor_provider> descriptor_provider)
64
+ {
65
+ if (value_loaders.empty () || !descriptor_provider) {
66
+ throw_xlio_exception (" loader/descriptor_provider cannot be null" );
67
+ }
68
+
69
+ // 1) Load raw config data - first in queue means higher priority.
70
+ std::map<std::string, std::experimental::any> aggregated_config_data;
71
+ while (!value_loaders.empty ()) {
72
+ auto loaded_data = value_loaders.front ()->load_all ();
73
+ aggregated_config_data.insert (loaded_data.begin (), loaded_data.end ());
74
+
75
+ value_loaders.pop ();
76
+ }
77
+
78
+ m_config_bundle.m_config_data = std::move (aggregated_config_data);
79
+
80
+ // 2) Load or build the descriptor structure
81
+ m_config_bundle.m_config_descriptor = descriptor_provider->load_descriptors ();
82
+
83
+ // 3) Validate all settings on construction (fail fast if invalid)
84
+ validate_config ();
85
+ }
86
+
87
+ config_manager::config_manager (std::queue<std::unique_ptr<loader>> &&value_loaders,
88
+ std::unique_ptr<descriptor_provider> descriptor_provider)
89
+ {
90
+ initialize_manager (std::move (value_loaders), std::move (descriptor_provider));
91
+ }
92
+
93
+ // Validate all config items against their descriptors & constraints.
94
+ // A real application might do more elaborate error handling/logging.
95
+ void config_manager::validate_config () const
96
+ {
97
+ // For each key-value in config_data, see if we have descriptor constraints
98
+ for (auto const &kv : m_config_bundle.m_config_data ) {
99
+ const auto &key = kv.first ;
100
+ const auto &value = kv.second ;
101
+
102
+ // Retrieve the descriptor (could be empty if not found)
103
+ auto param_desc = m_config_bundle.m_config_descriptor .get_parameter (key);
104
+ // If there's a specific type required, check constraints
105
+ if (!param_desc.validate (value)) {
106
+ // Throw an exception if validation fails
107
+ throw_xlio_exception (" Validation failed for key: " + key);
108
+ }
109
+ }
110
+ }
111
+
112
+ std::experimental::any config_manager::get_value_as_any (const std::string &key) const
113
+ {
114
+ // Try to find the key in the loaded data
115
+ auto it = m_config_bundle.m_config_data .find (key);
116
+ if (it == m_config_bundle.m_config_data .end ()) {
117
+ // Not found in data. Fallback to descriptor's default.
118
+ return m_config_bundle.m_config_descriptor .get_parameter (key).default_value ();
119
+ }
120
+
121
+ return (it->second );
122
+ }
0 commit comments