bes Updated for version 3.20.13
BESContainerStorageVolatile.cc
1// BESContainerStorageVolatile.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 "BESContainerStorageVolatile.h"
36#include "BESFileContainer.h"
37#include "BESInternalError.h"
38#include "BESSyntaxUserError.h"
39#include "BESInfo.h"
40#include "TheBESKeys.h"
41#include "BESUtil.h"
42#include "BESServiceRegistry.h"
43#include "BESDebug.h"
44
45// FIXME This is a lie, but it will help with debugging/design for the RemoteResources
46// FIXME design/fix. Remove this once that's done. jhrg 8/7/20
47#define MODULE "ngap"
48#define prolog std::string("BESContainerStorageVolatile::").append(__func__).append("() - ")
49
50using std::endl;
51using std::string;
52using std::list;
53using std::ostream;
54
70 BESContainerStorage(n), _root_dir(""), _follow_sym_links(false)
71{
72 string key = "BES.Data.RootDirectory";
73 bool found = false;
74 TheBESKeys::TheKeys()->get_value(key, _root_dir, found);
75 if (_root_dir == "") {
76 string s = key + " not defined in BES configuration file";
77 throw BESSyntaxUserError(s, __FILE__, __LINE__);
78 }
79
80 found = false;
81 key = (string) "BES.FollowSymLinks";
82 string s_str;
83 TheBESKeys::TheKeys()->get_value(key, s_str, found);
84 s_str = BESUtil::lowercase(s_str);
85 if (found && (s_str == "yes" || s_str == "on" || s_str == "true")) {
86 _follow_sym_links = true;
87 }
88}
89
90BESContainerStorageVolatile::~BESContainerStorageVolatile()
91{
93}
94
106{
107 BESContainer *ret_container = 0;
108
109 BESContainerStorageVolatile::Container_citer i;
110 i = _container_list.find(sym_name);
111 if (i != _container_list.end()) {
112#if 1
113 BESContainer *c = (*i).second;
114 ret_container = c->ptr_duplicate();
115#else
116 ret_container = (*i).second;
117#endif
118 }
119
120 return ret_container;
121}
122
139void BESContainerStorageVolatile::add_container(const string &sym_name, const string &real_name, const string &type)
140{
141 // The type must be specified so that we can find the request handler
142 // that knows how to handle the container.
143 // Changed sym_name to real_name to make the message clearer. jhrg 11/14/19
144 if (type.empty())
145 throw BESInternalError(string("Unable to add container '").append(real_name).append("', type of data must be specified"), __FILE__, __LINE__);
146
147 // if the container already exists then throw an error
148 BESContainerStorageVolatile::Container_citer i = _container_list.find(sym_name);
149 if (i != _container_list.end()) {
150 throw BESInternalError(string("A container with the name '").append(sym_name).append("' already exists"), __FILE__, __LINE__);
151 }
152
153 // make sure that the path to the container exists. If follow_sym_links
154 // is false and there is a symbolic link in the path then an error will
155 // be thrown. If the path does not exist, an error will be thrown.
156 BESUtil::check_path(real_name, _root_dir, _follow_sym_links);
157
158 // add the root directory to the real_name passed
159 string fully_qualified_real_name = BESUtil::assemblePath(_root_dir, real_name, false);
160
161 BESDEBUG("container","BESContainerStorageVolatile::add_container() - "
162 << " _root_dir: " << _root_dir
163 << " real_name: " << real_name
164 << " symbolic name: " << sym_name
165 << " fully_qualified_real_name: " << fully_qualified_real_name
166 << " type: " << type
167 << endl);
168
169 // Create the file container with the new information
170 BESContainer *c = new BESFileContainer(sym_name, fully_qualified_real_name, type);
171 c->set_relative_name(real_name);
172
173 // add it to the container list
174 _container_list[sym_name] = c;
175}
176
195{
196 if (!c) {
197 throw BESInternalError("Unable to add container, container passed is null", __FILE__, __LINE__);
198 }
199 if (c->get_container_type().empty()) {
200 throw BESInternalError("Unable to add container, type of data must be specified", __FILE__, __LINE__);
201 }
202
203 string sym_name = c->get_symbolic_name();
204
205 BESContainerStorageVolatile::Container_citer i = _container_list.find(sym_name);
206 if (i != _container_list.end()) {
207 throw BESInternalError(string("A container with the name '").append(sym_name).append("' already exists"), __FILE__, __LINE__);
208 }
209
210 _container_list[sym_name] = c;
211}
212
220{
221 BESDEBUG(MODULE, prolog << "BEGIN: " << s_name << endl);
222 bool ret = false;
223 BESContainerStorageVolatile::Container_iter i = _container_list.find(s_name);
224 if (i != _container_list.end()) {
225 BESContainer *c = (*i).second;
226 _container_list.erase(i);
227 if (c) {
228 BESDEBUG(MODULE, prolog << "delete the container: "<< (void *) c << endl);
229 delete c;
230 }
231 ret = true;
232 }
233 BESDEBUG(MODULE, prolog << "END" << endl);
234 return ret;
235}
236
245{
246 BESDEBUG(MODULE, prolog << "BEGIN" << endl);
247 while (_container_list.size() != 0) {
248 Container_iter ci = _container_list.begin();
249 BESContainer *c = (*ci).second;
250 _container_list.erase(ci);
251 if (c) {
252 BESDEBUG(MODULE, prolog << "delete the container: "<< (void *) c << endl);
253 delete c;
254 }
255 }
256 BESDEBUG(MODULE, prolog << "END" << endl);
257 return true;
258}
259
267bool BESContainerStorageVolatile::isData(const string &inQuestion, list<string> &provides)
268{
269 bool isit = false;
270 BESContainer *c = look_for(inQuestion);
271 if (c) {
272 isit = true;
273 string node_type = c->get_container_type();
274 BESServiceRegistry::TheRegistry()->services_handled(node_type, provides);
275 }
276 return isit;
277}
278
294{
295 info.add_tag("name", get_name());
296 string::size_type root_len = _root_dir.length();
297 BESContainerStorageVolatile::Container_iter i = _container_list.begin();
298 BESContainerStorageVolatile::Container_iter e = _container_list.end();
299 for (; i != e; i++) {
300 BESContainer *c = (*i).second;
301 string sym = c->get_symbolic_name();
302 string real = c->get_real_name();
303 if (real.length() > root_len) {
304 if (real.compare(0, root_len, _root_dir) == 0) {
305 real = real.substr(root_len, real.length() - root_len);
306 }
307 }
308 string type = c->get_container_type();
309 show_container(sym, real, type, info);
310 }
311}
312
320void BESContainerStorageVolatile::dump(ostream &strm) const
321{
322 strm << BESIndent::LMarg << "BESContainerStorageVolatile::dump - (" << (void *) this << ")" << endl;
323 BESIndent::Indent();
324 strm << BESIndent::LMarg << "name: " << get_name() << endl;
325 if (_container_list.size()) {
326 strm << BESIndent::LMarg << "containers:" << endl;
327 BESIndent::Indent();
328 BESContainerStorageVolatile::Container_citer i = _container_list.begin();
329 BESContainerStorageVolatile::Container_citer ie = _container_list.end();
330 for (; i != ie; i++) {
331 BESContainer *c = (*i).second;
332 c->dump(strm);
333 }
334 BESIndent::UnIndent();
335 }
336 else {
337 strm << BESIndent::LMarg << "containers: none" << endl;
338 }
339 BESIndent::UnIndent();
340}
341
virtual BESContainer * look_for(const std::string &sym_name)
looks for the specified container using the symbolic name passed
virtual void show_containers(BESInfo &info)
show information for each container in this persistent store
virtual bool del_container(const std::string &s_name)
removes a container with the given symbolic name from the list and deletes it.
virtual bool isData(const std::string &inQuestion, std::list< std::string > &provides)
determine if the given container is data and what servies are available for it
BESContainerStorageVolatile(const std::string &n)
create an instance of this persistent store with the given name.
virtual bool del_containers()
removes all container
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void add_container(BESContainer *c)
add the passed container to the list of containers in volatile storage
provides persistent storage for data storage information represented by a container.
virtual void show_container(const std::string &sym_name, const std::string &real_name, const std::string &type, BESInfo &info)
add information for a container to the informational response object
virtual const std::string & get_name() const
retrieve the name of this persistent store
A container is something that holds data. E.G., a netcdf file or a database entry.
Definition: BESContainer.h:65
std::string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:221
virtual BESContainer * ptr_duplicate()=0
pure abstract method to duplicate this instances of BESContainer
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:73
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:232
void set_relative_name(const std::string &relative)
Set the relative name of the object in this container.
Definition: BESContainer.h:152
std::string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:180
Holds real data, container type and constraint for symbolic name read from persistence.
informational response object
Definition: BESInfo.h:63
exception thrown if internal error encountered
virtual void services_handled(const std::string &handler, std::list< std::string > &services)
returns the list of servies provided by the handler in question
error thrown if there is a user syntax error in the request or any other user error
static void check_path(const std::string &path, const std::string &root, bool follow_sym_links)
Is the combination of root + path a pathname the BES can/should access?
Definition: BESUtil.cc:382
static std::string lowercase(const std::string &s)
Definition: BESUtil.cc:254
static std::string assemblePath(const std::string &firstPart, const std::string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
Definition: BESUtil.cc:801
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:340
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:71