bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
BESContextManager.cc
1// BESContextManager.cc
2
3// This file is part of bes, A C++ back-end server implementation framework
4// for the OPeNDAP Data Access Protocol.
5
6// Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8//
9// This library is free software; you can redistribute it and/or
10// modify it under the terms of the GNU Lesser General Public
11// License as published by the Free Software Foundation; either
12// version 2.1 of the License, or (at your option) any later version.
13//
14// This library is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17// Lesser General Public License for more details.
18//
19// You should have received a copy of the GNU Lesser General Public
20// License along with this library; if not, write to the Free Software
21// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22//
23// You can contact University Corporation for Atmospheric Research at
24// 3080 Center Green Drive, Boulder, CO 80301
25
26// (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27// Please read the full copyright statement in the file COPYRIGHT_UCAR.
28//
29// Authors:
30// pwest Patrick West <pwest@ucar.edu>
31// jgarcia Jose Garcia <jgarcia@ucar.edu>
32
33#include "config.h"
34
35#include <cstdlib>
36#include <cerrno>
37#include <cstring>
38#include <mutex>
39
40#include "BESContextManager.h"
41#include "BESInfo.h"
42#include "BESDebug.h"
43
44using std::endl;
45using std::string;
46using std::ostream;
47
48BESContextManager *BESContextManager::d_instance = nullptr;
49static std::once_flag d_euc_init_once;
50
51#define MODULE "context"
52#define prolog std::string("BESContextManager::").append(__func__).append("() - ")
53
54BESContextManager::BESContextManager() {}
55
56BESContextManager::~BESContextManager() {}
57
63void BESContextManager::set_context(const string &name, const string &value)
64{
65 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
66
67 BESDEBUG(MODULE, prolog << "name=\"" << name << "\", value=\"" << value << "\"" << endl);
68 _context_list[name] = value;
69}
70
76void BESContextManager::unset_context(const string &name)
77{
78 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
79
80 BESDEBUG(MODULE, prolog << "name=\"" << name << "\"" << endl);
81 _context_list.erase(name);
82}
83
93string BESContextManager::get_context(const string &name, bool &found)
94{
95 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
96
97 string ret;
98 found = false;
99 // Use find() instead of operator[] to avoid inserting a default value at key
100 // if it does not exist int he map. jhrg 2/26/25
101 auto const i = _context_list.find(name);
102 if (i != _context_list.end()) {
103 ret = i->second;
104 found = true;
105 }
106
107 BESDEBUG(MODULE, prolog << "name=\"" << name << "\", found=\"" << found << "\" value:\"" << ret << "\"" << endl);
108
109 return ret;
110}
111
121int BESContextManager::get_context_int(const string &name, bool &found)
122{
123 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
124
125 string value = BESContextManager::TheManager()->get_context(name, found);
126
127 if (!found || value.empty()) return 0;
128
129 char *endptr;
130 errno = 0;
131 int val = strtol(value.c_str(), &endptr, /*int base*/10);
132 if (val == 0 && errno > 0) {
133 throw BESInternalError(string("Error reading an integer value for the context '") + name + "': " + strerror(errno),
134 __FILE__, __LINE__);
135 }
136 BESDEBUG(MODULE, prolog << "name=\"" << name << "\", found=\"" << found << "\" value: \"" << val << "\"" << endl);
137
138 return val;
139}
140
141uint64_t BESContextManager::get_context_uint64(const string &name, bool &found)
142{
143 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
144
145 string value = BESContextManager::TheManager()->get_context(name, found);
146
147 if (!found || value.empty()) return 0;
148
149 char *endptr;
150 errno = 0;
151 uint64_t val = strtoull(value.c_str(), &endptr, /*int base*/10);
152 if (val == 0 && errno > 0) {
153 throw BESInternalError(string("Error reading an integer value for the context '") + name + "': " + strerror(errno),
154 __FILE__, __LINE__);
155 }
156 BESDEBUG(MODULE, prolog << "name=\"" << name << "\", found=\"" << found << "\" value: \"" << val << "\"" << endl);
157 return val;
158}
159
160
161
162
167{
168 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
169
170 string name;
171 string value;
172 std::map<string, string, std::less<>> props;
173 auto i = _context_list.begin();
174 auto e = _context_list.end();
175 for (; i != e; i++) {
176 props.clear();
177 name = (*i).first;
178 value = (*i).second;
179 props["name"] = name;
180 info.add_tag("context", value, &props);
181 }
182}
183
191void BESContextManager::dump(ostream &strm) const
192{
193 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
194
195 strm << BESIndent::LMarg << prolog << "(this: " << (void *) this << ")" << endl;
196 BESIndent::Indent();
197 if (_context_list.size()) {
198 strm << BESIndent::LMarg << "current context:" << endl;
199 BESIndent::Indent();
200 auto i = _context_list.begin();
201 auto ie = _context_list.end();
202 for (; i != ie; i++) {
203 strm << BESIndent::LMarg << (*i).first << ": " << (*i).second << endl;
204 }
205 BESIndent::UnIndent();
206 }
207 else {
208 strm << BESIndent::LMarg << "no context" << endl;
209 }
210 BESIndent::UnIndent();
211}
212
214BESContextManager::TheManager()
215{
216 std::call_once(d_euc_init_once,BESContextManager::initialize_instance);
217 return d_instance;
218}
219
220void BESContextManager::initialize_instance() {
221 d_instance = new BESContextManager;
222#ifdef HAVE_ATEXIT
223 atexit(delete_instance);
224#endif
225}
226
227void BESContextManager::delete_instance() {
228 delete d_instance;
229 d_instance = 0;
230}
231
maintains the list of registered request handlers for this server
virtual void list_context(BESInfo &info)
Adds all context and their values to the given informational object.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual int get_context_int(const std::string &name, bool &found)
Get the value of the given context and return it as an integer.
virtual void set_context(const std::string &name, const std::string &value)
set context in the BES
virtual std::string get_context(const std::string &name, bool &found)
retrieve the value of the specified context from the BES
virtual void unset_context(const std::string &name)
set context in the BES
informational response object
Definition BESInfo.h:63
exception thrown if internal error encountered