Line data Source code
1 : /*
2 : ___________________________________________
3 : | _ ___ _ |
4 : | | | |__ \ | | |
5 : | | |__ ) |__ _ __ _ ___ _ __ | |_ |
6 : | | '_ \ / // _` |/ _` |/ _ \ '_ \| __| | HTTP/2 AGENT FOR MOCK TESTING
7 : | | | | |/ /| (_| | (_| | __/ | | | |_ | Version 0.0.z
8 : | |_| |_|____\__,_|\__, |\___|_| |_|\__| | https://github.com/testillano/h2agent
9 : | __/ | |
10 : | |___/ |
11 : |___________________________________________|
12 :
13 : Licensed under the MIT License <http://opensource.org/licenses/MIT>.
14 : SPDX-License-Identifier: MIT
15 : Copyright (c) 2021 Eduardo Ramos
16 :
17 : Permission is hereby granted, free of charge, to any person obtaining a copy
18 : of this software and associated documentation files (the "Software"), to deal
19 : in the Software without restriction, including without limitation the rights
20 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21 : copies of the Software, and to permit persons to whom the Software is
22 : furnished to do so, subject to the following conditions:
23 :
24 : The above copyright notice and this permission notice shall be included in all
25 : copies or substantial portions of the Software.
26 :
27 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 : SOFTWARE.
34 : */
35 :
36 : #include <string>
37 : #include <regex>
38 :
39 : #include <nlohmann/json.hpp>
40 :
41 : #include <ert/tracing/Logger.hpp>
42 :
43 : #include <AdminServerProvisionData.hpp>
44 : #include <functions.hpp>
45 :
46 :
47 : namespace h2agent
48 : {
49 : namespace model
50 : {
51 :
52 173 : AdminServerProvisionData::AdminServerProvisionData() {
53 173 : server_provision_schema_.setJson(h2agent::adminSchemas::server_provision); // won't fail
54 173 : }
55 :
56 11 : std::string AdminServerProvisionData::asJsonString(bool ordered, bool getUnused) const {
57 :
58 11 : nlohmann::json result = nlohmann::json::array();
59 :
60 11 : read_guard_t guard(rw_mutex_);
61 11 : if (ordered) {
62 : bool aux;
63 3 : for (auto it = ordered_keys_.begin(); it != ordered_keys_.end(); it++) {
64 2 : auto element = get(*it, aux);
65 2 : if (getUnused && element->employed()) continue;
66 2 : result.push_back(element->getJson());
67 2 : };
68 : }
69 : else {
70 10 : this->forEach([&](const KeyType& k, const ValueType& value) {
71 7 : if (!(getUnused && value->employed())) {
72 5 : result.push_back(value->getJson());
73 : }
74 7 : });
75 : }
76 :
77 : // Provision is shown as an array regardless if there is 1 item, N items or none ([]):
78 22 : return (result.dump());
79 11 : }
80 :
81 125 : AdminServerProvisionData::LoadResult AdminServerProvisionData::loadSingle(const nlohmann::json &j, bool regexMatchingConfigured, const common_resources_t &cr) {
82 :
83 125 : std::string error{};
84 125 : if (!server_provision_schema_.validate(j, error)) {
85 4 : return BadSchema;
86 : }
87 :
88 : // Provision object to fill:
89 121 : auto provision = std::make_shared<AdminServerProvision>();
90 :
91 121 : if (provision->load(j, regexMatchingConfigured)) {
92 :
93 : // Push the key in the map:
94 117 : admin_server_provision_key_t key = provision->getKey();
95 :
96 : // Push the key just in case we configure ordered algorithm 'RegexMatching'.
97 : // So, we always have both lists available; as each algorithm finds within the proper
98 : // list, we don't need to drop provisions when swaping the matching mode on the fly:
99 117 : write_guard_t guard(rw_mutex_);
100 :
101 117 : if (!exists(key)) {
102 117 : ordered_keys_.push_back(key);
103 : }
104 :
105 117 : add(key, provision);
106 :
107 : // Set common resources:
108 117 : provision->setAdminData(cr.AdminDataPtr);
109 117 : provision->setConfiguration(cr.ConfigurationPtr);
110 117 : provision->setGlobalVariable(cr.GlobalVariablePtr);
111 117 : provision->setFileManager(cr.FileManagerPtr);
112 117 : provision->setSocketManager(cr.SocketManagerPtr);
113 117 : provision->setMockServerData(cr.MockServerDataPtr);
114 117 : provision->setMockClientData(cr.MockClientDataPtr);
115 :
116 117 : return Success;
117 117 : }
118 :
119 4 : return BadContent;
120 125 : }
121 :
122 123 : AdminServerProvisionData::LoadResult AdminServerProvisionData::load(const nlohmann::json &j, bool regexMatchingConfigured, const common_resources_t &cr) {
123 :
124 123 : if (j.is_array()) {
125 8 : for (auto it : j) // "it" is of type json::reference and has no key() member
126 : {
127 4 : LoadResult result = loadSingle(it, regexMatchingConfigured, cr);
128 4 : if (result != Success)
129 1 : return result;
130 4 : }
131 :
132 1 : return Success;
133 : }
134 :
135 121 : return loadSingle(j, regexMatchingConfigured, cr);
136 : }
137 :
138 10 : bool AdminServerProvisionData::clear()
139 : {
140 10 : write_guard_t guard(rw_mutex_);
141 10 : ordered_keys_.clear();
142 20 : return Map::clear_unsafe();
143 10 : }
144 :
145 118 : std::shared_ptr<AdminServerProvision> AdminServerProvisionData::find(const std::string &inState, const std::string &method, const std::string &uri) const {
146 118 : admin_server_provision_key_t key{};
147 118 : h2agent::model::calculateStringKey(key, inState, method, uri);
148 :
149 118 : bool exists{};
150 118 : auto result = get(key, exists);
151 236 : return (exists ? result:nullptr);
152 118 : }
153 :
154 5 : std::shared_ptr<AdminServerProvision> AdminServerProvisionData::findRegexMatching(const std::string &inState, const std::string &method, const std::string &uri) const {
155 5 : admin_server_provision_key_t key{};
156 5 : h2agent::model::calculateStringKey(key, inState, method, uri);
157 :
158 5 : read_guard_t guard(rw_mutex_);
159 5 : bool aux{};
160 8 : for (auto it = ordered_keys_.begin(); it != ordered_keys_.end(); it++) {
161 4 : auto provision = get(*it, aux);
162 4 : if (std::regex_match(key, provision->getRegex()))
163 1 : return provision;
164 4 : };
165 :
166 4 : return nullptr;
167 5 : }
168 :
169 : }
170 : }
171 :
|